2017-03-09 235 views
1
some_global = 15 
. 
. 
. 
@some_decorator(some_global) 
def someFunction(): 
. 
. 
. 
class SomeClass: 
    def someMethod(self): 
     global some_global 
     some_global = 5 

在我的代碼的上述抽象版本中,當全局方法運行後全局值傳遞到裝飾器並且全局值發生變化時,參數仍然在裝飾器中被識別爲15,而不是5.這是一個已知的問題?或者必須是我的代碼問題?全局函數裝飾器

回答

1

這取決於您的代碼行的順序。如果我們的裝飾器在some方法之前調用了一個參數,那麼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()