2010-05-03 49 views
3

我想使用另一個模塊的函數作爲裝飾器,但我需要它來操縱當前模塊的全局命名空間。從不同的模塊中使用python裝飾器函數

例如,我希望能夠從這個去:

class SomeClass: 
    pass 

root = SomeClass 

這樣:

from othermodule import decorator 

@decorator 
class Someclass: 
    pass 

任何想法?

+1

不代碼已經工作? – muckabout 2010-05-03 11:26:05

+0

我想他希望裝飾器中的代碼能夠在源類的全局範圍內定義一個根變量。恐怕這是對所有的python。 – 2010-05-03 12:56:05

+0

你可以有一個函數返回接受你的全局變量的裝飾器。 – 2018-03-02 21:14:21

回答

0

這是一個有點哈克,但嘗試這othermodule.py

import sys 
def decorator(cls): 
    mod = __import__(cls.__module__) 
    mod.root = cls 
+0

是的,工作,謝謝。其實我最終使用了mod = sys.modules [cls .__ module__],因爲__import__調用只返回頂層模塊(cls .__ module__)的深度爲4級 - 即mod1.mod2.mod3.mod4 – 2010-05-03 14:44:08

+0

順便提一句,'mod = __import__ (cls .__ module__,{},{},('*',))''將返回mod4模塊,而不是最外面的mod1包 – 2010-05-03 15:36:01

+0

這是一個直接的答案(儘管包和類似錯誤),但非常可怕碼。而且,對字符串文字使用'setattr'也是很愚蠢的。 'setattr(foo,'bar',baz)'拼寫爲'foo.bar = baz'。 – 2010-05-03 18:05:45

4

已經工作:

from othermodule import decorator 

@decorator 
class Someclass: 
    pass 

只要把othermodule.py

def decorator(cls): 
    #.... do something with cls 
    return cls 
+0

是的,我知道它在一般情況下工作,但這是事實,我想從導入模塊的裝飾器在原始模塊的全局範圍中定義一個變量,導致麻煩。 – 2010-05-03 14:26:34

4

有一個裝飾修改全局命名空間如果任何模塊,更不用說另一個模塊,是壞的,從來沒有必要。難以閱讀和維護遠離全局變異的代碼。您絕對應該考慮修改您的設計以避免可變全局狀態,尤其是隱式賦值。

0

而是直接裝飾的,你可以有一個返回裝飾並接受你的模塊的全局變量的函數:

def decorator(globals): 
    def dec(cls): 
     globals.root = cls 
     return cls 
    return dec 

@decorator(globals()) 
class SomeClass: 
    ...