装饰器介绍
# 装饰函数
def out_fun(function): # myfun被自动调用为function
def in_fun(z): # 由于myfunc(被装饰函数)存在一个参数,故in_fun(装饰函数也需要一个参数)
fig = function(z) ** 2 # 添加功能:计算myfun结果的平方,将in_fun替换myfunc
#function(z)本质上就是myfunc(x)
print(fig)
return fig
return in_fun
@out_fun # 添加装饰函数,通常用来在原函数基础上增加功能
# 被装饰函数
def myfunc(x):
y = x * 2 # 计算x的两倍
print(y)
return y
myfunc(3)
-
装饰器的作用:用于给被装饰函数增加功能,装饰函数就像一个加工厂,通过把被装饰函数作为装饰函数的参数进行。
-
装饰器的应用:当你在函数定义前使用
@装饰器名
时,Python 解释器会自动将该函数作为参数传递给装饰器。所以,myfunc
会被自动传递给out_fun
。 -
装饰器的执行流程:
- 首先,
out_fun
接收myfunc
作为参数,这个参数在装饰器内部被称为function
。 - 然后,
out_fun
返回一个新的函数in_fun
,这个函数包含了对myfunc
的增强或修改。 - 当你调用
myfunc(3)
时,实际上是在调用in_fun(3)
。 - 在
in_fun
中,首先调用function(z)
,这里的function
实际上是myfunc
,z
是传递给myfunc
的参数。 myfunc
执行并返回结果,这个结果被用于in_fun
中的后续操作,比如在你的示例中是计算平方并打印。- 最后,
in_fun
返回最终的结果。
- 首先,
-
参数的统一:装饰器中的
function
参数和被装饰函数的参数需要匹配,因为装饰器需要能够接收被装饰函数的所有参数,并将它们传递给被装饰函数。 -
返回值:装饰器必须返回一个函数,这个函数可以是一个新的函数,也可以是对原有函数的包装。这个返回的函数通常包含了对原函数的增强或修改。
-
装饰器的灵活性:装饰器不仅可以添加功能,还可以修改函数的行为,比如改变参数、返回值或者函数的执行环境等。
注意点:
1、由于装饰返回值必须是函数,所以在Python中。装饰器的典型结构是外层函数接收一个函数作为参数,并返回一个内层函数,这个内层函数会增强或修改原函数的行为。
2、python存在大量的自带装饰器,学习常用的可跳转https://gitcode.com/gh_mirrors/aw/awesome-python-decorator/overview?utm_source=csdn_github_accelerator&null
装饰器在python类中的运用——属性装饰器
属性装饰器是实现把方法转为属性的装饰器。
作用:
- 把方法转为属性,便于操作属性(如@property)
- 实现对属性的更改(验证)、查看、删除 (如@name.setter、@name.delete)
代码实例:
class 类名(object):
def __init__(self):
self.__名字 = xxx
@property
def 函数名(self):
return self.__名字
@函数名.setter
def 函数名(self, m):
self.__名字 += m
class Car(object):
def __init__(self, name, color):
self.name = name
self.color = color
self.__num = 20
@property
def num(self):
return self.__num
@num.setter
def num(self, x):
self.__num += x
c1 = Car('法拉利', '红色')
print(c1.name, c1.color, c1.num)
c1.num = 80
print(c1.num)
class Student(object):
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter
def name(self, new_name):
if not isinstance(new_name, str):
print('名字必须是一个字符串')
else:
self.__name = new_name
@name.deleter
def name(self):
print("已删除名字")
del self.__name
s1 = Student('张三')
print(s1.name)
s1.name = 111
s1.name = 'ak'
print(s1.name)
del s1.name
取一部分代码解释:
class Car(object):
def __init__(self, name, color):
self.name = name
self.color = color
self.__num = 20
@property
def num(self):
return self.__num
@num.setter
def num(self, x):
self.__num += x
@property把函数变成了属性,可以直接用c1.num来访问而不是c1.num()。
这就为下面的num.setter增加功能提供了便利