Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 装饰师执行?_Python_Python Decorators - Fatal编程技术网

Python 装饰师执行?

Python 装饰师执行?,python,python-decorators,Python,Python Decorators,玩decorator时,发现了一些奇怪的东西:我有如下简单的东西(一个将函数注册到列表的decorator: stored_f = [] def register(f): stored_f.append(f.__name__) return f @register def say_hello(name): print(f"Hello {name}") @register def ur_awesome(name): return f&quo

玩decorator时,发现了一些奇怪的东西:我有如下简单的东西(一个将函数注册到列表的decorator:

stored_f = []

def register(f):
    stored_f.append(f.__name__)
    return f

@register
def say_hello(name):
    print(f"Hello {name}")

@register
def ur_awesome(name):
    return f"{name}, you are awesome!"

我认为上面的代码不会执行任何操作(不会打印任何内容),因为我没有执行任何操作,但实际上打印命令“print(storaged_f)”将有一个输出:

['say_hello', 'ur_awesome']
这意味着register()中的“storaged_f.append(f.u name_u)”行实际上执行了两次。这对我来说很奇怪


我试图定义一个包装器()像往常一样,在register中,然后返回包装器,这个问题就会消失。但是我仍然不明白为什么上面的代码会部分执行decorator而不调用它。

导入并运行Python文件会执行它,添加带有
@register
的decorator会执行decorator

因此,即使您的脚本只包含变量声明、装饰器和两个函数定义,但当您运行它时,将执行这两个定义(定义函数)并执行它们上的装饰器函数,以便正确装饰函数

在你的评论之后补充:考虑这个:

stored_f = []

def register(f):
    stored_f.append(f.__name__)
    print('it runs!')
    return f

@register
def say_hello(name):
    print(f"Hello {name}")

@register
def ur_awesome(name):
    return f"{name}, you are awesome!"
您会发现,如果运行此脚本,输出为:

it runs!
it runs!
decorator中的所有代码都会运行,您只需返回它接收到的相同函数,因此
f
的前后工作方式相同

另外,如果在脚本末尾添加
say_hello(“john”)
,您会发现装饰程序不会再次运行,只有函数会再次运行

另外,比较一下:

stored_f = []

def register(f):
    stored_f.append(f.__name__)
    def decorated_f(*args):
        print('it runs!')
        f(*args)
    return decorated_f

@register
def say_hello(name):
    print(f"Hello {name}")

say_hello("john")
say_hello("pete")
这导致:

it runs!
Hello john
it runs!
Hello pete

也许这与您所期望的更接近。请注意,装饰程序不会返回原始函数,而是返回新函数。

根据Grimar的回答,我做了以下操作,可能会从另一个角度对其进行解释,至少对我自己是这样的:

def do_twice(f):
    print('This will be executed anyway')
    def wrapper():
        f()
        f()
    return wrapper

@do_twice
def say_hello():
    print('This is say hello')
输出:

This will be executed anyway
This is say hello
This is say hello
如果我跑步:

say_hello()
输出:

This will be executed anyway
This is say hello
This is say hello

为什么你认为它不会被执行?它不会“部分执行decorator而不调用它”;它完全执行decorator,通过调用它。“因为我没有执行任何东西”-但是
@register
执行
register
@jornsharpe因为我没有执行任何东西,它只是定义而已。就像我上一次说的,如果我把一个包装放在寄存器中,它绝对不会像我预期的那样做。“如果我把一个包装放在寄存器中,它绝对不会像我预期的那样做。”-因为您执行的是
寄存器
,而不是包装器。
寄存器
的主体将被执行。您在其中执行的任何操作都将完成。如果您更改
寄存器
的定义,以便不将其附加到存储在其中的
中,则它仍然是空的。decorator语法基本上是
say\h的缩写ello=register(say_hello)
。我想,但如果我错了就纠正:我想,如果我错了就纠正:@register不执行decorator,只执行@register()或say_hello()(注意两种情况下的括号)将执行。此外,如果我尝试遵循您的逻辑,为什么python只在寄存器中执行firs tline,然后停止?我添加了一些示例,希望能为您澄清情况。现在讲得通,谢谢,Grismary欢迎您-如果您觉得您的问题的答案足够好,请单击复选标记,以便问题出现答案为rs,这有助于其他人寻找答案或回答的问题。