本文主要介绍Python语言的一些特殊函数、属性、迭代器、生成器,属于Python语言的高级用法,也是真正体现Python语言特点的内容,十分精彩!
基本序列和映射规则
1 | def checkIndex(key): |
1 | s = ArithmeticSequence(1,2) |
9
1 | s[4]=2 # 自动调用对象s中的__setitem__函数 |
2
1 | s['four'] #触发TypeError |
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-f34801bc947b> in <module>()
----> 1 s['four']
<ipython-input-3-98492fefb016> in __getitem__(self, key)
23 从序列中取值
24 """
---> 25 checkIndex(key)
26
27 try: return self.changed[key] #是否修改了
<ipython-input-3-98492fefb016> in checkIndex(key)
3 检查索引是否有效,如果不是整型,引发TypeError;如果不是正数,引发IndexError
4 """
----> 5 if not isinstance(key, int): raise TypeError
6 if key < 0: raise IndexError
7
TypeError:
1 | s[-2] # 触发IndexError |
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-8-59e44d726fda> in <module>()
----> 1 s[-2]
<ipython-input-3-98492fefb016> in __getitem__(self, key)
23 从序列中取值
24 """
---> 25 checkIndex(key)
26
27 try: return self.changed[key] #是否修改了
<ipython-input-3-98492fefb016> in checkIndex(key)
4 """
5 if not isinstance(key, int): raise TypeError
----> 6 if key < 0: raise IndexError
7
8 class ArithmeticSequence:
IndexError:
子类化
除了上面定义这几个基本的序列/映射规则方法(4个方法)外(还有__del__和__iter__),也可以继承內建类型(如列表、字典)
1 | class CounterList(list): |
1 | c = CounterList(range(10)) |
4 5
2
property函数
对象的属性一般是通过访问函数获取或者设置,如果有多个属性的时候,不仅需要记住访问函数的名字,而且需要记住所有的属性名称,使用起来不方便。这个问题可以通过property函数解决
1 | class Rectange: |
1 | r = Rectange() |
(150, 100) 150 100
迭代器对象
在for循环中,前面只讨论对对序列和字典进行迭代。实际上,任何对象,只要实现了\(__iter__\)方法,该对象也可以在for中迭代。迭代规则相比列表来讲: 1. 不需要占用很多内存,一个一个计算; 2. 使用迭代器更通用、更简单、更优雅。
1 | class Fibs: |
1 | fibs = Fibs() |
1597
1 | #內建函数iter可以将可迭代对象转换为迭代器 |
1 2
1 | # 迭代器也可以转化为序列 |
1 | ti = TestIterator() |
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
生成器函数
- 循环生成器/生成器推导式和列表推导式的区别
1 | g = (i**2 for i in range(2,5)) #相对列表推导式,增加圆括号,输出一个迭代器 |
4 9 16
29
1 | [i**2 for i in range(2,5)] # 列表推导式 |
[4, 9, 16]
- 递归生成器 > 关键字yeild每次产生一个值,函数冻结,等待唤醒,唤醒后从停止的那点开始执行
1 | def flatten(nested): |
1 | list(flatten(['bar','zoo',[1,[2,3]]])) |
['bar', 'zoo', 1, 2, 3]
1 | ['bar','zoo',[1,[2,3]]]+'' |
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-72-af92cc690507> in <module>()
----> 1 ['bar','zoo',[1,[2,3]]]+''
TypeError: can only concatenate list (not "str") to list
- 生成器方法
1 | def repeater(value): |
1 | r = repeater(42) |
'Hello, world!'
1 | r = repeater(42) |
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-91-1af8ac817cac> in <module>()
1 r = repeater(42)
----> 2 r.send("new") # 必须要在生成器挂起的时候才可以发送信息,也就是在yield第一次执行之后。
TypeError: can't send non-None value to a just-started generator
- 生成器的替代方法
1 | def flatten(nested): |
1 | list(flatten(['bar','zoo',[1,[2,3]]])) |
['bar', 'zoo', 1, 2, 3]
参考资料
- Magnus Lie Hetland著,司维等人译,Python基础教程(第2版),2017
1 |