您的位置:首页 > 编程语言 > Python开发

python-迭代器和生成器

2018-03-06 14:51 676 查看
'''
property函数可以用0,1,3或4个参数来调用。如果没用参数,产生的属性既不可读,也不
可写。如果只使用一个参数调用(一个取值方法),产生的属性是只读的。第三个参数(可选)用于
删除特性的方法(它不要参数)。第四个参数(可选)是一个文档字符串。

property的四个参数分别叫做fget,fset,fdel,doc
'''

#静态成员方法和类成员方法
#静态方法和类成员方法分别在创建的时分别被装入staticmethod类型和classmethod类型
#的对象中。静态方法的定义没有self参数,且能够被类本身直接调用,类方法在定义需要名为
#cls的类似self的参数,类成员方法可以直接用类的具体对象调用,但cls参数是自动被绑定到类的
__metaclass__=type
class MyClass:
def stamethod():
print("static method!")
stamethod=staticmethod(stamethod)
def clsmethod(cls):
print("class method!",cls)
clsmethod=classmethod(clsmethod)

'''
装饰器:能对任何可调用的对象进行包装,可以用于方法,也可以用于函数
使用@操作符,在方法(或函数)的上方将装饰器列出。
'''
class MyClass:
@staticmethod#静态方法
def stamethod():
print("static method!")

@classmethod#类成员方法
def clsmethod(cls):
print("class method!",cls)

MyClass.stamethod()
MyClass.clsmethod()

'''
__getattr__、__setattr__

拦截对象的所有特性访问是可能,这可以使用旧式类实现,因为property方法不能使用
__getattribute__(self,name):当特性name被访问时自动被调用(只能在新式类中使用)
__getattr__(self,name):当特性name被访问且对象没有相应的特性时被自动调用
__setatr__(self,name,value):当试图给特性name赋值时会被自动调用
__delattr__(self,name):当试图删除特性name时被调用

'''

class  Rectangle:
def __init__(self):
self.width=0
self.height=0
def __setattr__(self,name,value):
if name=='size':
self.width,self.height=value
else:
self.__dict__[name]=value
def __getattr__(self,name):
if name=='size':
return self.width,self.height
else:
raise AttributeError
#注意:__setattr__方法在所涉及的特性不是size时也会被调用,如果属性为size,则像self.width,self.height=value
#   执行操作,否则需要使用特殊的方法__dict__,用来代替普通的特性赋值操作
#     __getattr__方法只在普通的特性没有找到的时候调用

#迭代器用法
#特殊方法__iter__:是迭代器规则的基础

#迭代器规则:__iter__方法会返回一个迭代器,即具有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()
print(fibs.next())

#内建函数iter可以从可迭代的对象中获取迭代器

'''
#生成器:是一种用普通函数语法定义的迭代器,任何包含yield语句的函数称为生成器
函数每次执行完后(使用yield语句,函数被冻结:即函数停在那点等待被唤醒,
唤醒后又从停止的那点开始。
'''
#将一个列表的列表展开
lst=[[1,2,3],[7,9,0],[1,4,6]]#不能用于元素为字符串的列表
def MyExpend(lst):
for a in lst:
for b in a:
yield b
for ele in MyExpend(lst):
print(ele)

print(list(MyExpend(lst)))

#循环生成器:生成器推导式(生成器表达式),返回的时生成器
g=((i+2)**2 for i in range(2,27))
#或在函数中使用
sum(i**2 for i in range(10))

#递归迭代器:多层循环嵌套
def MyExp(ls):
try:
try:
ls+''#用于进行类型判断
except TypeError:pass
else:raise TypeError
for s in ls:
for k in MyExp(s):#递归生成器
yield k
except TypeError:
yield ls

print(list(MyExp(["TXY",['DOC',["TXT"]]])))

#通用生成器
'''
生成器是一个包含yield的函数,当它被调用时,函数体中的代码不会被执行,而会返回一个迭代器,
每次请求一个值时,就会执行生成器中的代码,直到遇到yield或者return语句。
yield意味生成一个值,return则为代表生成器要停止(return只有在一个生成器中才能无参调用)
'''

#使用普通函数模拟生成器
def MyExpFunc(ls):
result=[]
try:
try:#不要迭代类似字符串的对象
ls+''
except TypeError:pass
else :
raise TypeError
for i in ls:
for j in MyExpFunc(i):
result.append(j)
except TypeError:
result.append(ls)
return result

print(MyExpFunc([
4000
'a',['a','b'],['ab']]))
运行结果:

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: