Python 魔法方法、属性和迭代器(9) 持续更新
__metaclass__ = type
新类和旧类的区别
class NewStyle(object): pass class OldStyle(): pass
在类的作用域中 对 __metaclass__ 变量赋值,只会为这个类设定元类。关于元类可以搜索 python metaclasses
魔法方法之构造函数
class Class(): def __init__(self): print 'Init Class' _class = Class()
__del__ 是析构函数,垃圾回收钱调用的函数。
调用父类的构造方法
class Class1(): def __init__(self): print 'Init Class1' class Class2(Class1): def __init__(self): Class1.__init__(self) print 'Init Class2' _class = Class2()
新式类 Super 调用方法
class Class1(): def __init__(self): print 'Init Class1' class Class2(Class1): def __init__(self): super(Class2, self).__init__() print 'Init Class2' _class = Class2()
魔法方法之成员访问
序列的4个方法
__len__(self) 返回集合中所含项目的数量
__getitem__(self, item) 返回与所键对应的值
__setitem__(self, key, value) 存储键值
__delitem__(self, key) 删除键值
这些方法有以下几个要求
- 序列,如果键是负整数,要从末尾开始计数。 x[-n] 等价于 x[len(x) - n]
- 如果键是不适合的类型,引发TypeError异常
- 序列的索引是正取的类型,但超出范围,引发IndexError异常
示例
# coding=utf-8 # 确定使用新式类 __metaclass__ = type def checkIndex(key): if not isinstance(key, (int, long)):raise TypeError class 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[5]
分片操作也可以的
http://stackoverflow.com/questions/27850161/what-should-i-use-instead-of-getslice
继承列表、字典和字符串
Python标准库有三个标准序列和映射规则 UserList、UserString 和 UserDict。
如果实现一个内建列表相似的序列,可以继承List实现。
当继承内建类型时,实际上间接继承了object。因此自动成为新式类,因此意味着可以直接使用像super函数的特性了。
# 带访问计数的列表 class CounterList(list): def __init__(self,*args): super(CounterList,self).__init__(*args) self.counter = 0 def __getitem__(self, item): self.counter += 1 return super(CounterList,self).__getitem__(item) __list = CounterList(range(10)) print __list __list.reverse() del __list[3:6] print __list print __list[0] print __list[1] print __list.counter
当然这里counter不是完美的,比如访问列表元素还可以通过 pop 函数。
更多的魔法函数
http://pycoders-weekly-chinese.readthedocs.io/en/latest/issue6/a-guide-to-pythons-magic-methods.html
属性
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 r = Rectangle() r.width = 10 r.height = 5 print r.getSize() r.setSize((100, 200)) print r.getSize() print r.width print r.height
property函数
此函数须在新式类执行,否则会出现困惑的问题
__metaclass__ = type 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) r = Rectangle() r.width = 10 r.height = 5 print r.getSize() r.setSize((100, 200)) print r.getSize() print r.width print r.height print r.size
静态方法(Staticmethod)和类成员方法(Classmethod)
__metaclass__ = type class Class: @staticmethod def smeth(): print 'this is a static method' @classmethod def cmeth(cls): print 'this is a class method',cls def cmeth2(self): print 'this is a class method2 ',self # call static method Class.smeth() # call class method ___class = Class() ___class.cmeth() ___class.cmeth2()
静态函数和类成员函数区别是,静态函数没有self参数。
@staticmethod 这种语法叫装饰器。
当装饰器定义类成员方法时,cls参数会自动绑定到类。
__getattr__、__setattr__
# 特性name被访问时自动被调用(需在新式类使用) def __getattribute__(self, item): # 当特性name被访问且对象没有相应的特性时被自动调用 def __getattr__(self, item): # 当给特性name赋值时,自动调用 def __setattr__(self, key, value): # 删除特性时,调用 def __delattr__(self, item):
__metaclass__ = type class Rectangle: def __init__(self): self.width = 0 self.height = 0 def __setattr__(self, key, value): if key == 'size': self.width,self.height = value else: self.__dict__[key] = value def __getattr__(self, item): if item == 'size': return self.width, self.height else: raise AttributeError _class = Rectangle() _class.size = 100,200 print _class.size
因为__getattribute__拦截所有特性的访问(在新式类),也拦截对__dict__的访问!访问__getattibute__中与Self相关的特性时,使用超类的 __getarrtibute__方法(使用super函数)是唯一安全的途径。
迭代器
迭代的意思是重复做一些事很多次,就像在循环中做的那样。
任何一个对象只要实现了__iter__方法,就可以进行迭代。__iter__方法返回一个迭代器。所谓迭代器就是具有next方法的对象。调用next方法,迭代器就会返回它下一个值。如果迭代器没有值返回,引发 StopInteration异常。
在Python3.0中,迭代器对象实现__next__方法,而不是next。next(it)等3.0之前it.next()。
迭代器的关键就是,使用时,一个一个返回值的,与列表一次性返回所有值,不一样的。
斐波那契数列
class Fibs(): def __init__(self): self.a = 0 self.b = 1 def next(self): temp = self.a self.a, self.b = self.b, self.a + self.b return temp def __iter__(self): return self fibs = Fibs() for f in fibs: if f < 2000: print f else: break
iter函数 直接直接从可迭代的对象中获得迭代器
it = iter([1,2,3]) print it.next() print it.next()
迭代器得到序列
class Fibs(): def __init__(self): self.a = 0 self.b = 1 self.max_value = 2000 def next(self): temp = self.a self.a, self.b = self.b, self.a + self.b if self.a > self.max_value: raise StopIteration return temp def __iter__(self): return self fibs = Fibs() print list(fibs)
生成器
def flatten(nested): for sublist in nested: for element in sublist: yield element nested = [[1,2],[1,2],[1,2]] for num in flatten(nested): print num print list(flatten(nested))
输出
1
2
1
2
1
2
[1, 2, 1, 2, 1, 2]
生成器推导式
print ( (i+2)**2 for i in range(2,10) ) print [ (i+2)**2 for i in range(2,10) ] 输出 <generator object <genexpr> at 0x0000000002E6ACF0> [16, 25, 36, 49, 64, 81, 100, 121]
生成器推导式可以在当前的圆括号内直接使用,如函数调用
print sum( i for i in range(1,101))
递归生成器
处理任意层的嵌套
def flatten(nested): try: for sublist in nested: for element in flatten(sublist): yield element except TypeError: yield nested nested = [[1,2],12,2,2,2,2,[1,[33,44,[99,88]],2],[1,2]] print list(flatten(nested))
输出
[1, 2, 12, 2, 2, 2, 2, 1, 33, 44, 99, 88, 2, 1, 2]
这里还有一个缺陷就是,字符串会进行迭代,解决如下
def flatten(nested): try: try: nested+'' except Exception: pass else: raise TypeError for sublist in nested: for element in flatten(sublist): yield element except TypeError: yield nested nested = [['AAAABBB',1,2],12,2,2,2,2,[1,[33,44,[99,88]],2],[1,2]] print list(flatten(nested))
上述代码是通过字符串拼接来检查的,也可以用isinstance函数完成检查是不是字符串。
通用生成器
生成器函数时用def语句定义的,包含yield的部分,生成器的迭代器是函数返回的部分。合起来叫生成器。
生成器方法
http://wiki.jikexueyuan.com/project/start-learning-python/215.html
http://www.cnblogs.com/huxi/archive/2011/07/14/2106863.html
回溯策略-----八皇后经典算法


浙公网安备 33010602011771号