python 常用概念

原始字符串(raw strings)

原始字符串的产生正是由于有正则表达式的存在。原因是 ASCII 字符和正则表达式特殊字符间所产生的冲突。比如,特殊符号“\b”在ASCII 字符中代表退格键, 但同时 “\b”也是一个正则表达式的特殊符号, 代表 “匹配一个单词边界”。为了让 RE 编译器把两个字符“\b”当成你想要表达的字符串,而不是一个退格键,你需要用另一个反斜线对它进行转义,即可以这样写:“\b”。
但这样做会把问题复杂化,特别是当你的正则表达式字符串里有很多特殊字符时,就更容易令人困惑了。在第六章,我们曾介绍过原始字符串,它经常被用于简化正则表达式的复杂程度。事实上,很多 Python 程序员在定义正则表达式时都只使用原始字符串。
下面的例子用来说明退格键 “\b” 和正则表达式 “\b”(包含或不包含原始字符串)之间的区别:

m = re.match('\bblow', 'blow') #退格键,没有匹配
if m is not None: m.group()
...
m = re.match('\\bblow', 'blow') #用\转义后,现在匹配了
if m is not None: m.group()
...
'blow'
m = re.match(r'\bblow', 'blow') #改用原始字符串
if m is not None: m.group()
...
'blow'

你可能注意到我们在正则表达式里使用“\d”,没用原始字符串,也没出现什么问题。那是因为ASCII 里没有对应的特殊字符,所以正则表达式编译器能够知道你指的是一个十进制数字。


python3编码

对于python3,默认的编码类型为unicode,即当写下语句 my_str = ‘my_str’ 时, my_str保存的是经过utf-8 编码的数据.

当你想对其做一些流操作,比如socket.sendall()这种,因为网络IO只支持字节流,所以要使用 my_str_en = my_str.encode()将其编码为符合utf-8 规范的字节流, 对方接收后,即可使用 my_str_en.decode()将字节流解码


生成器(generator)

对于一个generator, 可以使用next()方法获取下一个值,直至最后抛出StopIteration错误,但通常使用for循环来迭代
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

这是定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'

但是用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:

>>> g = fib(6)
>>> while True:
...     try:
...         x = next(g)
...         print('g:', x)
...     except StopIteration as e:
...         print('Generator return value:', e.value)
...         break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
你可能会问,为什么list、dict、str等数据类型不是Iterator?
这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。


偏函数

把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单

int2 = functools.partial(int, base=2)
>>> int2('1000000')
64

创建偏函数时,实际上可以接收函数对象、*args和**kw这3个参数

int2('10010')
相当于
kw = { 'base': 2 }
int('10010', **kw)

##########################

max2 = functools.partial(max, 10)
实际上会把10作为*args的一部分自动加到左边,也就是:
max2(5, 6, 7)
相当于
args = (10, 5, 6, 7)
max(*args)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值