赞
踩
分类目录:《系统学习Python》总目录
从语法上来讲,函数装饰器可以被看作是它后边跟着的函数的运行时声明。函数装饰器使用起来只需要单独一行,就写在定义数或方法的def
语句之前。它包括@
符号、后面跟着所谓的元函数(Metafunction),也就是管理另一函数的函数(或其他可调用对象)。例如,Python2.4之后的静态方法可以用下面的装饰器语法编写:
class C:
@staticmethod
def meth():
pass
从内部来看,该语法和下面的写法有相同效果,也就是把函数传递给装饰器,并冉赋值回最初的函数名:
class C:
def meth():
pass
meth = staticmethod(meth)
装饰过程把方法名重新与装饰器的结果相绑定。最终效果是,调用方法函数的名称,实际上是触发了它staticmethod
装饰器的结果。因为装饰器会返回任何种类的对象,这也可以让装饰器在每次调用时都增加一层逻辑。装饰器函数可以返回原来的函数本身,或者一个新的代理对象,该代理对象用于保存传给装饰器的原来的函数,原来的函数将会在额外逻辑层执行后间接地运行。
有了这些功能,下面是在Python2.X或Python3.X中编写静态方法的一种更好的方式:
class Spam:
numInstances = 0
def __init__(self):
Spam.numInstances = Spam.numInstances + 1
@staticmethod
def printNumInstances():
print(Spam.numInstances)
输入:
a = Spam()
b = Spam()
c = Spam()
a.printNumInstances()
Spam.printNumInstances()
输出:
3
3
因为classmethod
和property
内置数也接受和返回函数,所以它们也能以相同的方式用作装饰器:
class Methods:
def imeth(self, x):
print([self, x])
@staticmethod
def smeth(x):
print([x])
@classmethod
def cmeth(cls, x):
print([cls, x])
@property
def name(self):
return self.__class__.__name__
输入:
obj = Methods()
obj.imeth(1)
obj.smeth(2)
obj.cmeth(3)
obj.name
输出:
[<__main__.Methods object at 0x000001EA161891F0>, 1]
[2]
[<class '__main__.Methods'>, 3]
'Methods'
我们需要记住的是,staticmethod
和它这里的装饰器近亲都是内置函数;它们可以在装饰语法中使用,只是因为它们把一个函数当作参数并且返回一个可调用对象,而原来的函数将与该对象重新绑定。实际上,任何这样的函数都可以通过这种方式使用,也包括后面的文章将会介绍的我们自己编写的用户定义函数。
参考文献:
[1] Mark Lutz. Python学习手册[M]. 机械工业出版社, 2018.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。