目录
一、常用装饰器
#装饰器
def decorator(obj):
def wrapper(*args,**kwargs):
'''
函数里面可以操作自己想加入的功能;
加上*args,**kwargs两个参数,即表示:
无论被修饰的函数/类有几个参数、什么类型,都可以用该装饰器装饰,
如果,没有写这两个参数,那就必须被装饰的函数/类有
几个参数,装饰器就写死为几个参数;就达不到想要的效果
'''
print("执行装饰器")
res=obj(*args,**kwargs)
return res
return wrapper
#装饰器可装饰函数:
@decorator
def add(x,y):
return x+y
#装饰器可装饰类:
@decorator
class Math:
def __init__(self,x,y,z):
self.x=x
self.y=y
self.z=z
def shengfa(self):
return self.x * self.y * self.z
if __name__ == '__main__':
a=add(2,3)
print(a)
m=Math(1,2,3)
print(m.shengfa())
二、最高级函数装饰器,需要带上参数
user = 'admin'
pwd = 'admin123'
# 装饰器包含3层,最外层接收装饰器参数auth_type,第二层outter,接收装饰的函数func,其余与装饰器无异
def auth(auth_type):
def outter(func):
def wrapper(*args, **kwargs):
if auth_type == 'local':
username = input("Enter your username: ").strip()
password = input("Enter your password: ").strip()
if user == username and pwd == password:
print("Access granted")
else:
print("Access denied")
else:
print('不用验证')
return func()
return wrapper
return outter
# 一般的装饰器不带括号与参数,带参数时一般逻辑更为复杂,如:装饰器中需要根据参数不同,走不同逻辑
@auth(auth_type='local1')
def index():
print('welcome to the index page')
return 'index'
三、描述符+装饰器
#描述符 + 装饰器 应用于类class,描述符用来限制参数类型,装饰器用来给类添加属性
#众所周知,python是弱类型的语言;但是,很多时候,我们在class实例化传参时,
# 需要限定不同的参数用不同的数据类型;这个时候就需要描述符的应用来代理要描述的参数
#描述符指:一个类,中重写了__get__()、__set__()、__delete__()方法中的一个,
# 但是,数据描述符都必须将三个函数重写;功能也要自己添加
class Typed():
def __init__(self,key,type):
'''
:param key: 描述的属性关键字
:param type: 所描述的属性期待的数据类型
'''
self.key=key
self.type=type
def __set__(self, instance, value):
'''
注释:这个函数的参数是默认的;
instance ;实例对象本身,
value :描述的对象的属性的值\即实例化的传参值
'''
#为了实现需求:限制传入参数的类型,这里采用if语句
if not isinstance(value,self.type):
raise TypeError("参数类型错误,%s的类型不是%s"%(self.key,self.type))
#抛出异常,你也可以不抛出异常,直接print
else:
instance.__dict__[self.key]=value
def __get__(self, instance, owner):
'''
注释:这个函数的参数是默认的;
instance ;实例对象本身,
owner :描述的对象的所属的类
'''
return instance.__dict__[self.key]
def __delete__(self, instance):
'''
注释:这个函数的参数是默认的;
instance ;实例对象本身
'''
instance.__dict__.pop(self.key)
#上面实现了数据描述符的编写,下面举例使用描述符
#结合:装饰器+描述符
def decorator(*args,**kwargs):
def wrapper(obj):
for key,type in kwargs.items():#将字典转换称元祖对:(key,type)
setattr(obj,key,Typed(key,type))#利用描述符添加属性,描述符主要限制类型;
return obj
return wrapper
@decorator(name=str,age=int,gender=str)
class People:
'''
总的来说:描述符描述属性,就是绕了一个弯,
调用了描述符类的__get__()、__set__()、__delete__()方法,
而不是在类自身的方法;
这样可以实现,参数类型的限制
'''
# 利用描述符代理属性,当People实例化时,就会触发Typed()实例化,
# 同时,触发__set__(),传入属性值在dict属性字典中;
# 在调用People实例对象的name\age属性时,会触发Typed()的__get__()方法
def __init__(self,name,age):
self.name=name
self.age=age
if __name__ == '__main__':
people=People("张三",18)#不会报错
print(people.name)
print(People.__dict__)
print(people.__dict__)
# people1=People(12,"张三")#会报错
装饰器的写法不一;按照需求来写;
四、列表生成式
列表生成式是一种简洁的语法,用于快速创建列表。它允许我们在一行代码中生成一个新的列表,而不需要使用传统的循环语句。列表生成式的基本语法是在一个方括号内使用表达式来定义列表的元素,并可以结合条件语句和循环语句来筛选和转换元素。
下面是列表生成式的一些常见用法:
-
基本形式:[expression for item in iterable] 这种形式会遍历可迭代对象iterable中的每个元素,将表达式expression应用于每个元素,并将结果添加到新的列表中。
-
带有条件的列表生成式:[expression for item in iterable if condition] 在基本形式的基础上,可以添加一个条件语句if condition来筛选元素。只有满足条件的元素才会被添加到新的列表中。
-
嵌套的列表生成式:[expression for item in iterable1 for item2 in iterable2] 可以在列表生成式中嵌套使用多个for循环,用于生成多维列表。每个循环都会遍历相应的可迭代对象,并将结果组合成新的列表。
下面是一个示例,演示了如何使用列表生成式来生成一个包含1到10之间偶数的列表:
even_numbers = [x for x in range(1, 11) if x % 2 == 0]
print(even_numbers) # 输出: [2, 4, 6, 8, 10]
列表生成式可以简化代码,使得列表的创建更加简洁和高效。但需要注意的是,如果列表生成式过于复杂或包含大量的元素,可能会降低代码的可读性和性能。在使用列表生成式时,需要根据实际情况进行权衡和选择。
五、生成器
对比列表生成式与生成器;
# -------------------列表生成式----------------
num = [x for x in range(10) if x % 2 == 0]
print(num)
# -------------------生成器--------------------
n = (x for x in range(10) if x % 2 == 0)
print(n) # <generator object <genexpr> at 0x0000029DD96C7BC0>
# 返回是一个生成器对象 而不是一个实际的列表或元组,生成器在数据量特别大的时候节省性能的,弊端就是不能随意获取,需要依次获取__next__();
print(n.__next__()) # 0
print(n.__next__()) # 2
print(n.__next__()) # 4
# 一般是使用函数创造生成器:返回不用return,而是使用关键字yield
def fib(max):
# 斐波那契数列是指这样一个数列:1,1,2,3,5,8,13,21,34,55,89……这个数列从第3项开始 ,每一项都等于前两项之和
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
x = fib(10) # <generator object fib at 0x000001E1A62A7CA0> 生成器对象
print(x)
print(x.__next__()) # 1
print(x.__next__()) # 1
print(x.__next__()) # 2
def consumer(name):
print("%s 准备吃包子啦!" % name)
while True:
baozi = yield
print("包子【%s】来了,被【%s】吃了!" % (baozi, name))
c = consumer('zhangsan')
c.__next__()
c.send('肉馅儿') #包子【肉馅儿】来了,被【zhangsan】吃了!
c.__next__() #包子【None】来了,被【zhangsan】吃了!
效果展示:
5.1 协程
import time
def consumer(name):
'''客户'''
print("%s 准备吃包子啦!" % name)
while True:
baozi = yield
print("包子【%s】来了,被【%s】吃了!" % (baozi, name))
c = consumer('zhangsan')
c.__next__()
c.send('肉馅儿')
c.__next__()
def producer(name):
'''
协程
单线程下的并行效果,,,,异步io雏形
:param name:
:return:
'''
c = consumer("zhangshan")
c2 = consumer("lisi")
c.__next__()
c2.__next__()
print("producer开始准备做包子了……")
for i in range(10):
time.sleep(1)
print('做了2个包子')
c.send(i)
c2.send(i)
producer('alex')
运行起来,并行效果,两个函数一起异步交叉一样。理解异步io雏形