2010-05-03 58 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: 
    ...