容器、迭代器、生成器,闭包,装饰器,作用域,动态添加属性和方法

'''
容器是一系列元素的集合,str、list、set、dict、file、sockets对象都可以看作是容器,容器都可以被迭代(用在for,while等语句中),因此他们被称为可迭代对象。
可迭代对象实现了__iter__方法,该方法返回一个迭代器对象。
迭代器持有一个内部状态的字段,用于记录下次迭代返回值,它实现了__next__和__iter__方法,迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果。
生成器是一种特殊的迭代器,它的返回值不是通过return而是用yield。
'''
'''判断是否可以迭代'''
from collections import Iterable
print(isinstance("abc",Iterable))
print(isinstance(100,Iterable))


'''闭包'''
print('-----------1-----------------------')
def line_conf(a,b):
def line(x):
return a*x + b
return line
line1 = line_conf(1,1)
line2 = line_conf(4,5)
print(line1(5))
print(line1(6)) #闭包的作用就是在下次用同样的参数a、b时,函数会自动保存参数a、b,只需输入参数x即可。
print(line2(5))
print(line1(7))


'''装饰器'''
print('-----------2-----------------------')
def w1(func):
def inner():
print('---正在验证权限----')
if True:
func()
else:
print('---验证不通过---')
return inner

@w1
def f1():
print('---f1---')

@w1
def f2():
print('---f2---')

f1()
f2()


'''两个装饰器'''
print('-----------3-----------------------')
#定义函数:完成包裹数据
def makeBold(fn):
def wrapped():
print('------1-------')
return "" + fn() + ""
return wrapped

#定义函数:完成字体斜体
def makeItalic(fn):
def wrapped():
print('-----2------')
return "" + fn() + ""
return wrapped

#装饰器在代码执行到改行时候,已经开始装饰了,而非下边的调用test3()时候才开始装饰,即在调用test3()时候已经装饰好了。
@makeBold
@makeItalic
def test3():
print('-----3------')
return "hello world-3"

ret = test3() #先执行makeBold装饰器,装饰器中的wrapped函数中遇到函数fn()就会向下执行,
# 由于下边是makeItalic装饰器,则将makeItalic赋值给该fn(),同理makeItalic中的fn()将被赋值予test3(),依次调用执行。
print(ret)



'''有参函数装饰器'''
print('-----------4-----------------------')
def func(functionName):
print('---func---1---')
def func_in(*args,**kwargs): #如果a,b没有定义,那么会导致99行的调用失败
print('---func_in---1---')
functionName(*args,**kwargs) #如果没有把a,b当做实参进行传递,那么会导致调用92行的函数失败
print('---func_in---2---')

print('---func---2---')
return func_in

@func
def test(a,b,c):
print('---------test-a=%d,b=%d,c=%d---------'%(a,b,c))

@func
def test2(a,b,c,d):
print('------test2-a=%d,b=%d,c=%d,d=%d-----'%(a,b,c,d))

test(11,22,33)
test2(11,22,33,44)


'''装饰器对带有返回值的函数进行装饰'''
print('-----------5-----------------------')
def func16(functionName):
print('-----func----1-----')
def func_in():
'''如果这样写,127行会得不到值。
因为在执行test16()时,会先执行他的装饰器,装饰器中return func_in,则找到func_in()函数,
此函数中执行了装饰器装饰的函数,则去调用test16(),func_in()函数执行完并没有返回值,所以127行得不到返回值。
print('---func_in---1----')
functionName()
print('---func_in---2----')
'''
print('---func_in---1----')
ret16 = functionName() #保存返回来的haha
print('---func_in---2----')
return ret16 #把haha返回到128行处的调用

print('-----func----2-----')
return func_in

@func16
def test16():
print('------test16-----')
return "haha"

ret16 = test16()
print('test return value is %s'%ret16)


'''通用装饰器:无论装饰函数是否有参数,是否有返回值,该装饰器都适用。'''
print('-----------6-----------------------')
def func40(functionName):
def func_in(*args,**kwargs):
ret = functionName(*args,**kwargs)
return ret
return func_in

@func40
def test40():
print('----test40----')

@func40
def test41():
print('----test41-----')
return "hahahaha"

@func40
def test42(a):
print('-----test42------a=%d--'%a)

ret40 = test40()
print('test40 return value is %s'%ret40)

ret41 = test41()
print('test41 return value is %s'%ret41)

ret42 = test42(111)
print('test42 return value is %s'%ret42)



'''带有参数的装饰器'''
print('-----------7-----------------------')
def func_arg(arg):
def func(functionName):
def func_in():
print('---记录日志-arg=%s---'%arg)
if arg=="heihei":
functionName()
functionName()
else:
functionName()
return func_in
return func

@func_arg("heihei") #带有参数的装饰器,能够起到在运行时,有不同的功能。
def test34():
print('----test34----')

@func_arg("haha")
def test35():
print("----test35----")

test34()
test35()


'''作用域'''
print(globals()) #全局变量
print(locals()) #局部变量
print('-----------8-----------------------')
#LEGB规则:Python使用LEGB的顺序来查找一个符号对应的对象。
# locals->enclosing function(外部嵌套函数的命名空间,闭包中常见)->globals->builtins(内建模块的命名空间)


'''python动态添加属性以及方法'''
#动态语言:可以在运行的过程中,修改代码
#静态语言:编译时已经确定好代码,运行过程中不能修改
print('-----------9-----------------------')
class Person():
def __init__(self,newName):
self.name = newName

def eat(self):
print("-----%s正在吃-------"%self.name)

def run(self):
print("-----%s正在跑-------"%self.name)

laowang = Person("老王")
print(laowang.name)
laowang.addr = "北京..."
print(laowang.addr)

laozhao = Person("老赵")
# print(laozhao.addr) 此处报错,因为laozhao这个实例对象还没有添加addr这个属性

Person.num = 100 #给类添加属性
print(laowang.num)
print(laozhao.num)

p1 = Person("p1")
p1.eat()
p1.run = run
# p1.run() #虽然p1对象中run属性已经指向了207行的函数,,,到那时这句代码还不正确
#因为run属性指向的函数是后来添加的,即p1.run()的时候,并没有把p1当做第一个参数self,
#导致了第207行的函数调用的时候,出现缺少参数的问题。

import types
p1.run = types.MethodType(run,p1) #给对象添加实例方法的正确方式
p1.run()

@staticmethod #静态方法装饰器
def ttest():
print('---------static method----------')

Person.ttest = ttest #静态方法、类方法是跟着类走的
Person.ttest()

@classmethod #静态方法装饰器
def printNumm(cls):
print('------class method--------')

Person.printNumm = printNumm
Person.printNumm()

class Personn():
__slots__ = ("name","age") #定义类的时候定义一个特殊的_slots_变量,来限制该class实例能添加的属性。
#_slots_定义的属性仅对当前类实例起作用,对类和继承的子类是不起作用的。

pp = Personn()
pp.name = "老王"
pp.age = 20
# pp.score = 60 类实例在添加属性时候,非_slots_变量元组中的属性不能添加,类在添加时可以随意添加属性。
Personn.score = 80 #可以添加类的属性

#互换两个数字
a = 9
b = 4
a,b = b,a
print(str(a),str(b))


'''生成器:一边循环一边计算的机制,成为生成器。保存了计算值的算法,并没有执行,而是什么时候调用这个值什么时候执行。'''
print('-----------10-----------------------')
# alist = [x*2 for x in range(100000000000)] #直接生成,会内存错误
#①第一种方式实现生成器
blist = (x*2 for x in range(100000000000)) #什么时候用什么时候生成
print(next(blist))
print(next(blist))

#②第二种方式实现生成器
def creatNum():
print("-----start-----")
a,b = 0,1
for i in range(5):
print('----1----')
yield b #yield作用:暂停程序,将yield后的值返回
print('-----2------')
a,b = b,a + b
print('----3-----')
print('------stop------')

#创建了一个生成器
scq = creatNum()
print(next(scq)) #next(scq):让scq这个生成器对象开始执行,如果是第一次执行,那么就从creatNum的开始部分执行,
#如果是之前已经执行过了,那么就从上一次停止的位置开始执行。
print(scq.__next__()) #next(scq)和scq.__next__()作用一样

print('-----')
for num in scq:
print(num)


#send("haha"):作用类似于next(),不同的是send会将"haha"赋值给yeild b的整体结果。
print('-----------10-----------------------')
def test28():
i = 0
while i<5:
temp = yield i
print(temp)
i += 1

t28 = test28()
print(t28.__next__())
print(t28.__next__())
print(t28.send("haha")) #从上一次暂停的地方开始执行,即yield i处开始执行,将"haha的值赋值给yield i整体的结果即temp,所以执行print(temp)输出haha。"

#切换多个任务一起执行:协程,协程比进程和线程要快。
def ttest1():
while True:
print('--1--')
yield None

def ttest2():
while True:
print('--2--')
yield None

tt1 = ttest1()
tt2 = ttest2()
while True:
tt1.__next__()
tt2.__next__()

转载于:https://www.cnblogs.com/wisir/p/10097581.html

你可能感兴趣的:(容器、迭代器、生成器,闭包,装饰器,作用域,动态添加属性和方法)