Python中的特殊方法、属性和迭代器
来源:互联网 发布:mac 磁盘恢复 编辑:程序博客网 时间:2024/05/20 11:49
特殊方法
有的名称前后都有两个下划线,如__future__
,由这些名字组成的集合所包含的方法称为特殊方法。
构造方法
构造方法是一个特殊方法。
创建构造方法:
class FooBar: def __init__(self): self.somevar = 42f = FooBar() print f.somevar #42
也可以在构造方法中传入参数:
class FooBar: def __init__(self,value=42): self.somevar = value
子类重写父类的构造方法
如果一个类的构造方法被重写,那么就需要调用超类的构造方法。可以通过调用超类构造方法的未绑定版本或使用super函数。
调用未绑定的超类构造方法
在Python3.0中推荐使用super函数。
class Bird: def __init__(self): self.hungry = True def eat(self): if self.hungry: print 'Aaah...' self.hungry = False else: print 'No,thanks!'class SongBird(Bird): def __init__(self): Bird.__init__(self) # 调用父类构造方法 self.sound = 'Squawk!' def sing(self): print self.soundsb = SongBird()sb.sing() #Squawk!sb.eat() #Aaah...sb.eat() #No,thanks!
调用一个实例的方法时,该方法的self参数会自动绑定到实例上,这称为绑定方法。
如果直接调用类的方法,如Bird.__inint__
,那么就没有实例会被绑定,就要提供需要的self参数,这样的方法称为未绑定方法。
使用super函数
class SongBird(Bird): def __init__(self): super(SongBird,self).__init__() # 注意super括号里面是逗号 self.sound = 'Squawk!' def sing(self): print self.sound
属性
property函数
使用property函数可以创建属性。
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)
property函数创建了一个属性,其中访问器函数被用作参数(先是取值,然后是赋值),这个属性命名为size。
r = Rectangle()r.width = 10r.height = 5print r.size #(10, 5)
property()函数中的两个函数分别对应的是获取属性的方法、设置属性的方法,这样一来,外部的对象就可以通过访问size的方式,来达到获取、设置的目的。
当需要更改上例中的getSize、setSize函数的名称时,如果这些方法是作为接口让用户调用的,那么对用户而言就要修改自己调用的方法名,很麻烦,使用了proprty()后,用户就不需担心这种问题了。
静态方法和类成员方法
静态方法和类成员方法分别在创建时装入Staticmethod类型和Classmethod类型的对象中。静态方法的定义没有self参数,能被类本身直接调用。类方法在定义时需要名为cls的参数,类成员方法可以直接用类的具体对象调用。
class MyClass: @staticmethod def smeth(): print 'This is a static method' @classmethod def cmeth(cls): print 'This is a class method of',clsMyClass.smeth() #This is a static methodMyClass.cmeth() #This is a class method of <class '__main__.MyClass'>
上面的代码中没有实例化类
迭代器
迭代器规则
只要对象实现了__iter__
方法就可以进行迭代。该方法会返回一个迭代器。
使用迭代器实现的斐波那契数列:
class Fibs: def __init__(self): self.a = 0 self.b = 1 def next(self): #实现了next方法的对象是迭代器 self.a,self.b = self.b,self.a + self.b return self.a def __iter__(self): #实现了__iter__方法的对象是可迭代的 return self
每次访问next的时候生成下一个值:
fibs = Fibs()for f in fibs: if f > 1000: print f #1597 break
从迭代器得到序列
迭代器和可迭代对象还能转换为序列,比如使用list构造方法显示地将迭代器转换为列表:
class TestIterator: value = 0 def next(self): self.value += 1 if self.value>10 : raise StopIteration #用于结束迭代 return self.value def __iter__(self): return selfti = TestIterator()print list(ti) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
生成器
创建生成器
创建生成器和创建函数类似,任何包含yield(ES6中也有这个关键字)语句的函数称为生成器。以一个例子来讲解。
首先创建一个列表的列表:
nested = [[1,2,3],[4,5],[6]]
然后写一个生成器:
def flatten(nested): for sublist in nested: for element in sublist: yield element # 每产生一个值,函数就会被冻结
每次访问到yield语句时,产生一个值,并且函数被冻结,等待被重新唤醒。函数被重新唤醒后就从停止的那点开始执行。
下面在生成器上迭代来使用所有的值:
for num in flatten(nested): print num
输出:
123456
也可以通过list函数来访问:
print list(flatten(nested)) #[1, 2, 3, 4, 5, 6]
递归生成器
如果想要处理任意层的嵌套,应该使用递归。
def flatten(nested): try: for sublist in nested: #可迭代的情况 for element in flatten(sublist): yield element except TypeError: # 和不可迭代的情况 yield nestedprint list(flatten([[[1],2],3,4,[5,[6,7,[8,9]]]])) #[1, 2, 3, 4, 5, 6, 7, 8, 9]
这样做有一个问题:如果nested是一个类似于字符串的对象,那么会导致无穷递归。因为一个字符串的第一个元素是另一个长度为1的字符串,而长度为1的字符串的第一个元素就是字符串本身。
我试了一下,会抛出异常RuntimeError: maximum recursion depth exceeded
def flatten(nested): try: #不要迭代类似字符串的对象 try: nested + '' except TypeError: pass else: raise TypeError for sublist in nested: #可迭代的情况 for element in flatten(sublist): yield element except TypeError: # 和不可迭代的情况 yield nestedprint list(flatten('123')) #['123']
如果表达式nested + ”引发了一个TypeError说明它不是类似字符串的序列,可以被迭代;否则,引发一个自己的TypeError,直接返回这个类似字符串序列。这是检查一个对象是不是类似于字符串的最简单、最快速的方法。
- Python中的特殊方法、属性和迭代器
- python特殊属性和方法的运用
- python特殊属性和方法的运
- Python特殊属性和方法的运用
- Python中的__getitem__和__setitem__特殊方法
- python类中的特殊属性and特殊方法and特殊文件
- Python中的特殊方法
- 第九章 特殊方法,属性和迭代器
- 15. Python脚本学习笔记十五特殊方法、属性和迭代器
- 关于python中的特殊方法
- Python的特殊属性和用法
- 【Lua】访问C#中的属性和方法-特殊情况-带有out和ref关键字
- Python(私有变量)类中的特殊方法
- Python(私有变量)类中的特殊方法
- Python(私有变量)类中的特殊方法
- Python(私有变量)类中的特殊方法
- Python(私有变量)类中的特殊方法
- Python(私有变量)类中的特殊方法
- hibernate无法自动建表的原因
- cheerio爬取网页数据,存储到MySQL数据库
- 用Vue开发小程序的框架
- 欢迎使用CSDN-markdown编辑器
- jq实现一些注册页面的按钮点击和不可点击
- Python中的特殊方法、属性和迭代器
- PHP实现简单对称加密
- 高数 07.02 偏导数
- 阿里内部创新自动化测试工具开放啦
- 软件调试笔记43
- 网络编程预习1
- RecyclerView多条目
- NULL
- [Javascript 高级程序设计]学习心得记录11 js的BOM