最近在看的是《python 基础教程》,第九章的小知识点比较多,记录一下课本上的示例,都是手敲过一遍的加深一下印象。
主要介绍了类相关的内容,迭代器,生成器等基础知识。
# super方法
class Bird:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print('Ahaaa...')
self.hungry = False
else:
print('No Thanks')
class SongBird(Bird):
def __init__(self):
# 如果没有super这行调用父类构造方法,则无法访问父类的eat函数和成员hungry
# 出现错误AttributeError: 'SongBird' object has no attribute 'hungry'
super(SongBird, self).__init__()
self.sound = 'Squawk!'
def sing(self):
print(self.sound)
sb = SongBird()
sb.sing()
sb.eat() # Ahaaa...
sb.eat() # No Thanks
# 成员访问,基本的序列和映射规则__len__(self),__getitem__(self,key),,
def checkIndex(key):
if not isinstance(key, (int, int)): raise TypeError
if key < 0:
raise IndexError
class ASquence:
def __init__(self, start=0, step=1):
"""
初始化算术序列,
"""
self.start = start
self.step = step
self.changed = {}
def __getitem__(self, key):
"""
该方法返回与所给键对应的值
"""
checkIndex(key)
try:
return self.changed[key] # 修改了吗?
except KeyError:
return self.start + key * self.step # 计算值
def __setitem__(self, key, value):
"""
按一定的崔则存储和key相关的value,该值随后可使用__getitem__来获取
"""
checkIndex(key)
self.changed[key] = value # 保存修改后的值
s = ASquence(1, 2)
print(s[4]) # 9
s[4] = 2
print(s[4]) # 2
print(s[5]) # 11
# 子类化列表,字典和字符串
# 如果希望实现一个和内建列表行为类似的序列,可以子类化list来实现
class CounterList(list):
def __init__(self, *args):
super(CounterList, self).__init__(*args)
self.counter = 0
def __getitem__(self, index):
self.counter += 1
return super(CounterList, self).__getitem__(index)
c1 = CounterList(range(10))
print(c1) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
c1.reverse()
print(c1) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
del c1[3:6] # [9, 8, 7, 3, 2, 1, 0]
print(c1)
print(c1.counter) # 0
c1[4] + c1[2] # 每次列表中的元素被访问,counter就会自增,所以下面为2
print(c1.counter) # 2
print(c1[3])
print(c1.counter) # 3
# property函数
"""
property有0,1,2,3,4个参数,fget,fset,fdel,doc,可以用关键字参数设置其中若干个
eg property(fset=**,doc=**)
"""
class Rectangle:
def __init__(self):
self.width = 0
self.height = 0
def setSize(self, size):
self.width, self.height = size
def getSize(self):
return self.width, self.height
size = property(getSize, setSize) # 可以直接使用size而不用调用getSize/setSize
r = Rectangle()
r.width = 10
r.height = 5
print(r.size) # (10, 5)
r.size = 150, 100
print(r.size) # (150, 100)
# 静态方法和类成员函数
"""
可以使用装饰器描述
"""
class MyClass:
@staticmethod
def smeth():
print('This is a static method')
@classmethod
def cmeth(cls): # 类成员方法需要cls类似于self
print('This is a class of ', cls)
MyClass.smeth() # This is a static method
MyClass.cmeth() # This is a class of <class '__main__.MyClass'>
# __getattr__,__setattr__
# 迭代器__iter__,返回一个迭代器,具有next方法
"""
在3.0中,迭代器需要实现__next__方法,并使用next访问,
next(it)等于2.X版本中的it.next()
"""
class Fibs:
def __init__(self):
self.a = 0
self.b = 1
def __next__(self):
self.a, self.b = self.b, self.a + self.b
return self.a
def __iter__(self):
return self
fibs = Fibs()
for f in fibs:
if f > 100:
print(f) # 144
break
# 从迭代器得到序列
class TestIter:
value = 0
def __next__(self):
self.value += 1
if self.value > 10: raise StopIteration
return self.value
def __iter__(self):
return self
ti = TestIter()
print(list(ti)) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 生成器
'''
生成器是一个包含yield关键字的函数,当它被调用时,在函数体中的代码不会被执行,而会返回一个迭代器,
每次请求一个值,就会执行生成器中的代码,知道遇到一个yield或者return语句,yield语句意味着生成一个值,
return语句意味着生成器要停止。
'''
def flattern(nested):
try:
for sublist in nested:
for elem in flattern(sublist):
yield elem
except TypeError:
yield nested
print(list(flattern([[[1], 2], 3, 4, [5, [6, 7]], 8]))) # [1, 2, 3, 4, 5, 6, 7, 8]