魔法方法、属性和迭代器

作者:追风剑情 发布于:2017-12-19 15:24 分类:Python

示例

  1. # -*- coding: cp936 -*-
  2. #魔法方法、属性和迭代器
  3.  
  4. class NewStyle(object):#继承object的类作为新式类
  5. pass
  6.  
  7. #这句声明之后定义的类都为新式类
  8. __metaclass__ = type #使用新式类
  9. #在Python3.0中都是新式类,不需要显示声明.
  10.  
  11. class FooBar:
  12. def __init__(self): #定义构造方法
  13. self.somevar = 42
  14.  
  15. class FooBar1:
  16. def __init__(self, value=42): #带形参的构造方法
  17. self.somevar = value
  18.  
  19. def __del__(self): #对象被回收前会调用析构方法
  20. print '析构方法被调用'
  21.  
  22. class A:
  23. def hello(self):
  24. print "Hello, I'm A."
  25.  
  26. class B(A):
  27. def hello(self): #重定A类的hello方法
  28. print "Hello, I'm B."
  29.  
  30. class Bird:
  31. def __init__(self):
  32. self.hungry = True
  33. def eat(self):
  34. if self.hungry:
  35. print 'Aaaah...'
  36. self.hungry = False
  37. else:
  38. print 'No. thanks!'
  39.  
  40. class SongBird(Bird):
  41. def __init__(self):
  42. #Bird.__init__(self) #调用父类的构造方法,这是旧版Python的写法
  43. super(SongBird, self).__init__() #新式类中可以这样写(推荐写法)
  44. #Python3.0中super函数可以不带任何参数。
  45. self.sound = 'Squawk!'
  46. def sing(self):
  47. print self.sound
  48.  
  49. #继承内建类型
  50. class CounterList(list):
  51. def __init__(self, *args):
  52. super(CounterList, self).__init__(*args)
  53. self.counter = 0
  54. def __getitem__(self, index):
  55. self.counter += 1
  56. return super(CounterList, self).__getitem__(index)
  57.  
  58. print '构造方法'
  59. f = FooBar()
  60. print f.somevar
  61.  
  62. f = FooBar1("This is a constructor argument")
  63. print f.somevar
  64.  
  65. print '重写超类方法'
  66. a = A()
  67. b = B()
  68. a.hello()
  69. b.hello()
  70.  
  71. sb = SongBird()
  72. sb.sing()
  73. sb.eat()
  74. sb.eat()
  75.  
  76. print '继承内建类型'
  77. cl = CounterList(range(10))
  78. print cl
  79. cl.reverse()
  80. print cl
  81. del cl[3:6]
  82. print cl
  83. print cl[4] + cl[2] #通过索引访问会调用__getitem__()方法
  84. print cl.counter
  85.  
  86. print '属性访问器方法'
  87. #在新式类中推荐用访问器访问属性
  88. class Rectangle:
  89. def __init(self):
  90. self.width = 0
  91. self.height = 0
  92. def setSize(self, size):
  93. self.width, self.height = size
  94. def getSize(self):
  95. return self.width, self.height
  96. #property函数只在新式类中有用
  97. #property(fget、fset、fdel、doc) 可以用关键字参数赋值
  98. #fdel是一个用于删除特性的方法(它不要参数)
  99. #doc是一个文档字符串
  100. size = property(getSize, setSize) #创建属性size
  101. #size = property(getSize) #创建只读属性size
  102.  
  103. r = Rectangle()
  104. r.width = 10
  105. r.height = 5
  106. print r.getSize()
  107. r.setSize((150, 100))
  108. print r.width
  109. r.size = 200, 300
  110. print r.width
  111.  
  112. print '静态方法和类成员方法'
  113. #老版本Python实现方式
  114. class MyClass:
  115. def smeth(): #静态方法没self参数
  116. print 'This is a static method'
  117. smeth = staticmethod(smeth) #手动包装(替换),现在smeth才是真正的静态方法。
  118. def cmeth(cls):#实例方法
  119. print 'This is a class method of ', cls
  120. cmeth = classmethod(cmeth) #手动包装(替换),现在cmeth才是真正的实例方法。
  121.  
  122. #Python2.4之后的实现方式
  123. class MyClass1:
  124. @staticmethod
  125. def smeth():#静态方法
  126. print 'This is a static method'
  127. @classmethod
  128. def cmeth(cls):#实例方法
  129. print 'This is a class method of ', cls
  130.  
  131. MyClass1.smeth()
  132. MyClass1.cmeth()
  133.  
  134. print '__getattr__、setattr__'
  135. #__getattribute__(self, name)当特性name被访问时自动被调用(只能在新式类中使用)
  136. #__getattr__(self, name)当特性name被访问且对象没有相应的特性时被自动调用。
  137. #__setattr__(self, name, value)当试图给特性name赋值时会被自动调用。
  138. #__delattr__(self, name)当试图删除特性name时被自动调用。
  139. class Rectangle1:
  140. def __init__(self):
  141. self.width = 0
  142. self.height = 0
  143. def __setattr__(self, name, value):#给特性赋值时会被调用
  144. if name == 'size':
  145. self.width, self.height = value
  146. else:
  147. #__dict__方法被用来代替普通的特性赋值操作
  148. self.__dict__[name] = value #必须这样赋值,否则会陷入死循环
  149. #在旧式类中特性没有被找到时会被调用
  150. #在新式类中会拦截所有特性访问
  151. def __getattr__(self, name):
  152. if name == 'size':
  153. return self.width, self.height
  154. else:
  155. raise AttributeError
  156.  
  157. print '迭代器__iter__'
  158. #实现了__iter__方法的对象可迭代
  159. #迭代器需要实现next方法
  160. #在旧版本中要求迭代器实现next方法
  161. #在Python3.0中要求迭代器实现__next__方法, 可以这样迭代next(it)
  162. class Fibs:
  163. def __init__(self):
  164. self.a = 0
  165. self.b = 1
  166. def next(self):
  167. self.a, self.b = self.b, self.a+self.b #生成下一个斐波那契数
  168. return self.a
  169. def __iter__(self):
  170. return self
  171. fibs = Fibs()
  172. for f in fibs:#迭代对象
  173. if f > 1000:
  174. print f
  175. break;
  176.  
  177. #内建函数iter可以从可迭代的对象中获得迭代器
  178. it = iter([1,2,3])
  179. print it.next()
  180. print it.next()
  181.  
  182. print '从迭代器得到序列'
  183. class TestIterator:
  184. value = 0
  185. def next(self):
  186. self.value += 1
  187. if self.value > 10: raise StopIteration #结束迭代
  188. return self.value
  189. def __iter__(self):
  190. return self
  191. ti = TestIterator()
  192. print list(ti)
  193.  
  194. print '生成器'
  195. #生成器是一个包含yield关键字的函数
  196. #yield语句意味着应该生成一个值
  197. #return语句意味着生成器要停止执行(return语句只有在一个生成器中使用时才能进行无参数调用)
  198. #创建一个生成器函数
  199. def flatten(nested):
  200. for sublist in nested:
  201. for element in sublist:
  202. yield element
  203. nested = [[1,2], [3,4], [5]]
  204. #迭代nested
  205. for num in flatten(nested):
  206. print num
  207. #或者直接转成list输出
  208. print list(flatten(nested))
  209.  
  210. print '生成器推导式'
  211. g = ((i+2)**2 for i in range(2,27))
  212. print g.next()
  213. print sum(i**2 for i in range(10))#生成器推导式可以作为参数直接作用
  214.  
  215. print '递归迭代'
  216. def flatten1(nested):
  217. try:
  218. #不要迭代类似字符串的对象
  219. try: nested + '' #通过检查可拼接性
  220. except TypeError: pass
  221. else: raise TypeError
  222. for sublist in nested:
  223. for element in flatten1(sublist):
  224. yield element
  225. except TypeError:
  226. yield nested
  227.  
  228. print list(flatten1(nested))
  229.  
  230. print '生成器方法' #Python2.5引入
  231. print '生成器的send方法'
  232. def repeater(value):
  233. while True:
  234. new = (yield value)#用括号闭合yield表达式
  235. if new is not None: value = new
  236.  
  237. r = repeater(42)
  238. print r.next()
  239. print r.send("Hello. world!")#给生成器发送参数
  240. #生成器还有两个方法throw方法、close方法
  241.  
  242. #生成器在旧版Python中不可用
  243. #下面用普通函数来实现生成器
  244. def flatten2(nested):
  245. result = []
  246. try:
  247. try: nested + ''
  248. except TypeError: pass
  249. else: raise TypeError
  250. for sublist in nested:
  251. for element in flatten1(sublist):
  252. result.append(element)
  253. except TypeError:
  254. result.append(nested)
  255. return result
  256.  
  257. print list(flatten2(nested))

运行测试

11111.png

标签: Python

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号