Python学习笔记之魔法方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习笔记之魔法方法相关的知识,希望对你有一定的参考价值。
魔法方法(特殊方法):名称以双下划线和双下划线结尾的方法。
这些方法会在特殊情况下被Python直接调用,几乎没有直接调用的必要。
__init__():构造函数
__del__():析构函数
在其他语言中对象可能被要求属于某一个类,或被要求实现接口,但在Python中只是简单的要求它遵守几个给定的规则。
如一个序列类,为了实现规则,则需要实现以下魔法方法:
__len__(self):返回集合中所含项目的数量
__getitem__(self,key):返回与所给键对应的值
__setitem__(self,key,value):修改
__delitem__(self,key):在使用del语句时调用
#创建一个无穷序列 def checkIndex(key): if not isinstance(key,int): print(‘it\‘s not a num‘) raise TypeError if key<0: raise ValueError class ArithmeticSequence(object): """docstring for ArithmeticSequence""" 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): checkIndex(key) self.changed[key] = value s = ArithmeticSequence(1,2) print(s[4]) s[4] = 2 print(s[4]) print(s[‘four‘]) #运行结果 Traceback (most recent call last): it‘s not a num File "F:\Python_Program\input.py", line 32, in <module> print(s[‘four‘]) File "F:\Python_Program\input.py", line 17, in __getitem__ checkIndex(key) File "F:\Python_Program\input.py", line 6, in checkIndex raise TypeError TypeError
对于这些特殊方法的实现可以直接通过继承列表等类。
property函数:
class rectangle(object): """docstring for rectangle""" def __init__(self): self.width = 0 self.length = 0 def set_size(self,size): self.width,self.length = size def getSzie(self): return self.width,self.length size = property(getSzie,set_size) r = rectangle() r.width = 5 r.length = 10 print(r.size)
property函数将size变成一个真正的特性,在使用property函数之前只可以通过访问器set_size和getSize来访问。
为了在访问特性时可以执行代码,必须使用以下魔法方法:
- __getattribute__(self,name):当特性name被访问时自动调用
- __getattr__(self,name):当特性name被访问且对象没有相应的的特性时自动调用
- __setattr__(self,name,value):试图给特性name赋值时自动调用
- __delattr__(self,name):试图删除特性时调用
class rectangle(object): """docstring for rectangle""" def __init__(self): self.width = 0 self.length = 0 def __setattr__(self,name,value): if name == ‘size‘: self.width,self.length = value else: self.__dict__[name] = value def __getattr__(self,name): if name == ‘size‘: return self.width,self.length else: raise AttributeError #size = property(getSzie,set_size) r = rectangle() r.width = 5 r.length = 10 print(r.size)
迭代器:
__iter__:迭代器规则的基础,会返回一个迭代器,迭代器就是一个具有__next__方法的对象,调用__next__方法时,迭代器会返回它的下一个值
class Fibs(object): """docstring for 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 s in fibs: if s > 1000: print(s) break
内建函数iter可以从可迭代对象中获得迭代器
class Fibs(object): """docstring for 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() x = iter(fibs) print(x.__next__()) #运行结果 1 [Finished in 0.9s]
生成器:一种用普通函数语法定义的迭代器。
以下举例说明生成器
对于一个嵌套列表的列表,打印列表中的数字
def flatten(nested): for sublist in nested: for i in sublist: yield i nested = [[1,2,3],[2,3],[1]] for num in (flatten(nested)): print(num)
1
2
3
2
3
1
[Finished in 0.1s]
任何包含yield的函数称为生成器,它每次产生多个值,每产生一个值函数就被冻结,函数被重新唤醒后就从停止那里开始执行。
如果要对内嵌类型不明的列表进行迭代
def flatten(nested): try: try: nested + ‘ ‘ except TypeError: pass else: raise TypeError for sublist in nested: for i in flatten(sublist): yield i except TypeError: yield nested nested = [[1,2,3],[2,3],1,‘abc‘] for num in (flatten(nested)): print(num)
以上是关于Python学习笔记之魔法方法的主要内容,如果未能解决你的问题,请参考以下文章