Sha*_*cis 2 python function decorator python-3.x python-decorators
我正在教自己如何在一些在线教程的帮助下编写代码.我遇到了"装饰者",我似乎可以理解它是如何工作的但是有些困扰我.这是给出的代码:
def decor(func):
def wrap():
print("-----------")
func()
print("-----------")
return wrap
def print_text():
print("Hello World")
decorated = decor(print_text)
decorated()
output:
-----------
Hello World
-----------
Run Code Online (Sandbox Code Playgroud)
我想要了解的事情是:
为什么你必须调用"return wrap"而不是"return wrap()"?然而,如果你不这样做,你会得到一个"TypeError:'NoneType'对象不可调用.
当我赋值装饰变量的时候.为什么我还必须使用"print_text"而不是"print_text()",如果我这样做会引发相同的TypeError?
当我使用变量"装饰".为什么我必须像函数一样调用它(最后添加()).当我用"装饰"或"打印(装饰)"来称它时,它说的是完全不同的东西?
抱歉愚蠢的问题.但我刚刚开始,所以请耐心等待.另外,请让您的回复初学者友好.谢谢
在Python中,几乎所有东西都是一个对象.函数也是对象.您可以通过他们的名字引用它们:
>>> def print_text():
... print("Hello World")
...
>>> print_text # **no** call here, this is just referencing the object
<function print_text at 0x10e3f1c80>
>>> print_text() # With a call, so now we *run* the function
Hello World
Run Code Online (Sandbox Code Playgroud)
添加()到名称告诉Python调用该函数,这导致它实际执行函数体,没有调用,它只是显示名称引用的内容.
您也可以将函数对象分配给其他名称.仍然可以调用其他名称,调用函数:
>>> other_name = print_text
>>> other_name
<function print_text at 0x10e3f1c80>
>>> other_name()
Hello World
Run Code Online (Sandbox Code Playgroud)
所以other_name只是对同一个对象的另一个引用,并且添加()(调用表达式)会导致执行函数对象.print_text()并other_name()执行完全相同的操作,在函数内部运行代码.
这就是func里面的名字decor(); 它是对同一个函数对象的引用.你把它传递给了decor(print_text).只有在以后,wrapper()表达式内部才会func()调用该函数对象.如果你传入了print_text(),你将传入None函数返回的对象,并且None无法调用:
>>> return_value = print_text()
Hello World
>>> return_value is None
True
>>> return_value()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
Run Code Online (Sandbox Code Playgroud)
接下来,return wrapper将新创建的wrapper函数对象返回给调用者.如果你这样做return wrapper(),你将返回函数的结果,而不是函数对象本身.
装饰器的重点是用一个新的对象替换原始的函数对象,这个对象会执行额外的操作,这就是装饰器返回该替换对象的原因(在您的示例中wrapper),以便将来调用时decorated(),您可以调用该包装器函数调用原始函数之前和之后的额外内容(通过func名称,引用print_text()).
那么什么decor(some_function)是返回一个新的函数对象,一个打印的东西,调用传入的函数对象,然后打印其他东西.然后可以使用该新函数对象替换旧的函数对象.
| 归档时间: |
|
| 查看次数: |
484 次 |
| 最近记录: |