文章目录
一、怎么决定代码是封装到类里还是模块里
• 当你需要许多具有相似行为(方法)但不同状态(特性)的实例时,使用对象是最好的
选择。
• 类支持继承,但模块不支持。
• 如果你想要保证实例的唯一性,使用模块是最好的选择。不管模块在程序中被引用多少
次,始终只有一个实例被加载。
• 如果你有一系列包含多个值的变量,并且它们能作为参数传入不同的函数,那么最好
将它们封装到类里面。
例如,你可能会使用以 size 和 color 为键的字典代表一张彩色图片。你可以在程序中为每张图片创建不同的字典,并把它们作为参数传递给像scale() 或者 transform() 之类的函数。但这么做的话,一旦你想要添加其他的键或者函数会变得非常麻烦。为了保证统一性,应该定义一个 Image 类,把 size 和 color 作为特性,把 scale() 和 transform() 定义为方法。这么一来,关于一张图片的所有数据和可执行的操作都存储在了统一的位置。
• 用最简单的方式解决问题。使用字典、列表和元组往往要比使用模块更加简单、简洁且
快速。而使用类则更为复杂。
二、%旧式格式化与{}format新式格式化
1.%旧式格式化
转换类型
%s 字符串
%d 十进制整数
%x 十六进制整数
%o 八进制整数
%f 十进制浮点数
%e 以科学计数法表示的浮点数
%g 十进制或科学计数法表示的浮点数
%% 文本值 % 本身
简单例子
>>> '%s' % 42
'42'
>>> '%s' % 7.03
'7.03'
>>> '%f' % 7.03
'7.030000'
>>> '%e' % 7.03
'7.030000e+00'
>>> '%g' % 7.03
'7.03'
>>> '%d%%' % 100
'100%'
>>> n = 42
>>> f = 7.03
>>> s = 'string cheese'
>>> '%d %f %s' % (n, f, s)
'42 7.030000 string cheese'
2.{}format新式格式化
旧式格式化方式现在仍然兼容。Python 2(将永远停止在 2.7 版本)会永远提供对旧式格式
化的支持。然而,如果你在使用 Python 3,新式格式化更值得推荐。
新式格式化最简单的用法如下所示:
代码如下(示例):
>>> '{} {} {}'.format(n, f, s)
'42 7.03 string cheese'
旧式格式化中传入参数的顺序需要与 % 占位符出现的顺序完全一致,但在新式格式化里,
可以自己指定插入的顺序:
>>> '{2} {0} {1}'.format(f, s, n)
'42 7.03 string cheese'
0 代表第一个参数 f ; 1 代表字符串 s ; 2 代表最后一个参数,整数 n
上面这些例子都是以默认格式打印结果的。旧式格式化允许在 % 后指定参数格式,但在新
式格式化里,将这些格式标识符放在 : 后。首先使用位置参数的例子:
>>> '{0:d} {1:f} {2:s}'.format(n, f, s)
'42 7.030000 string cheese'
三、使用正则表达式匹配
match() 并不是比较 source 和 pattern 的唯一方法。下面列出了另外一些可用的方法:
• search() 会返回第一次成功匹配,如果存在的话;
• findall() 会返回所有不重叠的匹配,如果存在的话;
• split() 会根据 pattern 将 source 切分成若干段,返回由这些片段组成的列表;
• sub() 还需一个额外的参数 replacement,它会把 source 中所有匹配的 pattern 改成
replacement。
1. 使用match()进行准确匹配
字符串 ‘Young Frankenstein’ 是以单词 ‘You’ 开头的吗?以下是一些带注释的代码:
>>> import re
>>> source = 'Young Frankenstein'
>>> m = re.match('You', source) # 从源字符串的开头开始匹配
>>> if m: # 匹配成功返回了对象,将它输出看看匹配得到的是什么
... print(m.group())
...
You
>>> m = re.match('^You', source) # 起始锚点也能起到同样作用
>>> if m:
... print(m.group())
...
You
尝试匹配 ‘Frank’ 又会如何?
>>> m = re.match('Frank', source)
>>> if m:
... print(m.group())
...
match() 什么也没有返回, if 也没有执行内部的 print 语句。如前所述, match()
只能检测以模式串作为开头的源字符串。但是 search() 可以检测任何位置的匹配:
2. 使用search()寻找首次匹配
使用 search() 在源字符串 ‘Young Frankenstein’ 的任意位置寻找模式 ‘Frank’ ,无
需通配符 .* :
>>> m = re.search('Frank', source)
>>> if m: # search返回对象
... print(m.group())
...
Frank
3. 使用findall()寻找所有匹配
之前的例子都是查找到一个匹配即停止。但如果想要知道一个字符串中出现了多少次字母
‘n’ 应该怎么办
>>> m = re.findall('n', source)
>>> m # findall返回了一个列表
['n', 'n', 'n', 'n']
>>> print('Found', len(m), 'matches')
Found 4 matches
4. 使用split()按匹配切分
下面的示例展示了如何依据模式而不是简单的字符串(就像普通的 split() 方法做的)将
一个字符串切分成由一系列子串组成的列表:
>>> m = re.split('n', source)
>>> m # split返回的列表
['You', 'g Fra', 'ke', 'stei', '']
5. 使用sub()替换匹配
这和字符串 replace() 方法有些类似,只不过使用的是模式而不是文本串:
>>> m = re.sub('n', '?', source)
>>> m # sub返回的字符串
'You?g Fra?ke?stei?'
6. 模式:定义匹配的输出
当使用 match() 或 search() 时,所有的匹配会以 m.group() 的形式返回到对象 m 中。如果
你用括号将某一模式包裹起来,括号中模式匹配得到的结果归入自己的 group (无名称)
中,而调用 m.groups() 可以得到包含这些匹配的元组,如下所示:
>>> m = re.search(r'(. dish\b).*(\bfish)', source)
>>> m.group()
'a dish of fish'
>>> m.groups()
('a dish', 'fish')
(?P< name >expr) 这样的模式会匹配 expr ,并将匹配结果存储到名为 name 的组中:
>>> m = re.search(r'(?P<DISH>. dish\b).*(?P<FISH>\bfish)', source)
>>> m.group()
'a dish of fish'
>>> m.groups()
('a dish', 'fish')
>>> m.group('DISH')

本文探讨了何时选择将代码封装到类还是模块中,以及%旧式格式化与{}
440

被折叠的 条评论
为什么被折叠?



