全局函数装饰器

时间:2017-03-09 08:25:25

标签: global-variables global decorator

some_global = 15
. 
. 
. 
@some_decorator(some_global)
def someFunction(): 
. 
. 
. 
class SomeClass:
    def someMethod(self):
        global some_global
        some_global = 5

在我的代码的上述抽象版本中,当在运行方法并且全局值更改后将全局传递到装饰器时,该参数仍然在装饰器中被识别为15,而不是5。这个已知的问题?或者必须是我的代码的问题?

1 个答案:

答案 0 :(得分:1)

这取决于代码行的顺序。如果我们的装饰器在某个方法之前使用参数调用,则some_global具有其初始值,否则如果在装饰器之前调用某个方法,则全局变量的值已更改。

使用此代码:

some_global = 15


def some_decorator(val):
    print("decorator val: {}".format(val))
    print("decorator global: {}".format(some_global))

    def real_decorator(function):
        def wrapper():
            function()

        return wrapper

    return real_decorator


class SomeClass:
    def some_method(self):
        global some_global
        some_global = 5
        print("method: {}".format(some_global))

如果你写

@some_decorator(some_global)
def some_function():
    print("function: {}".format(some_global))


SomeClass().some_method()

some_function()

然后输出

decorator val: 15
decorator global: 15
method: 5
function: 5

但输出此代码:

SomeClass().some_method()


@some_decorator(some_global)
def some_function():
    print("function: {}".format(some_global))


some_function()

将是:

method: 5
decorator val: 5
decorator global: 5
function: 5

我强烈建议您不要使用全局变量。

在您的情况下,您可以直接在装饰器的包装中使用它:

some_global = 15

def real_decorator(function):
    print("decorator: {}".format(some_global))

    def wrapper():
        print("wrapper: {}".format(some_global))
        function()

    return wrapper


class SomeClass:
    def some_method(self):
        global some_global
        some_global = 5
        print("method: {}".format(some_global))


@real_decorator
def some_function():
    print("function: {}".format(some_global))


SomeClass().some_method()

some_function()

在这段代码中,包装器中的变量值仅取决于代码底部的函数调用顺序,并且等于某些函数中的值:

SomeClass().some_method()

some_function()