背景
python每周一练20191103:使用Flask、Redis和Celery执行异步任务使用了@,有不少初学者对@犯疑。

装饰器decorator
返回值为另一函数的函数,通常使用 @wrapper语法。 装饰器的常见例子包括classmethod()
和 staticmethod()
。
装饰器语法只是一种语法快捷方式,以下两个函数定义在语义上完全等价:
def f(...): ...f = staticmethod(f)@staticmethoddef f(...): ...
同的样概念也适用于类,但通常较少这样使用。有关装饰器的详情可参见 函数定义 和 类定义 的文档。
- 示例1:
def test(f): print("before ...") f() print("after ...") @testdef func(): print("func was called")
执行结果
before ...func was calledafter ...
Python解释器读到函数修饰器“@”的时候,后面步骤会是这样了:
- 去调用 test函数,test函数的入口参数就是那个叫“func”的函数;
- test函数被执行,入口参数的(也就是func函数)会被调用(执行);
- 示例2:
def funcA(A): print("function A")def funcB(B): print(B(2)) print("function B")@funcA@funcBdef func(c): print("function C") return c**2
执行结果
function C4function Bfunction A
这个例子告诉我们func有两个装饰器,是从下网上调用的。
注意:
- 函数先定义,再修饰它;反之会编译器不认识;
- 修饰符“@”后面必须是之前定义的函数或类;
- 每个函数可以有多个修饰符。
参考资料
- 本文最新版本地址
- 本文涉及的python测试开发库 谢谢点赞!
- 本文相关海量书籍下载
- python工具书籍下载-持续更新
- https://docs.python.org/3/howto/descriptor.html
- 本文配套视频 https://sn9.us/file/18113597-406685860 后面20分钟
描述器descriptor
任何定义了 __get__()
, __set__()
或 __delete__()
方法的对象。当类属性为描述器时,它的特殊绑定行为就会在属性查找时被触发。通常情况下,使用 a.b 来获取、设置或删除属性时会在 a 的类字典中查找名称为 b 的对象,但如果 b 是描述器,则会调用对应的描述器方法。理解描述器的概念是更深层次理解 Python 的关键,因为这是许多重要特性的基础,包括函数、方法、属性、类方法、静态方法以及对超类的引用等等。
有关描述符的方法的详情可参看 实现描述器。
class property(fget=None, fset=None, fdel=None, doc=None)
fget 是获取属性值的函数。 fset 是用于设置属性值的函数。 fdel 是用于删除属性值的函数。并且 doc 为属性对象创建文档字符串。
class C(): def __init__(self): self._x = None def getx(self): return self._x def setx(self, value): self._x = value def delx(self): del self._x x = property(getx, setx, delx, "I'm the 'x' property.") demo = C()demo.x = 5print(demo.x)print(demo.getx())
执行结果
55
更快捷的方式:
class C(): def __init__(self): self._x = None @property def x(self): """I'm the 'x' property.""" return self._x @x.setter def x(self, value): self._x = value @x.deleter def x(self): del self._x demo = C()demo.x = 5print(demo.x)
@property 装饰器会将 x() 方法转化为同名的只读属性的 "getter",并将 x的文档字符串设置为 "I'm the 'x' property."
执行结果
5
原著是一个有趣的人,若有侵权,请通知删除
还没有人抢沙发呢~