Using python decorator functions from a different module
16,640
Solution 1
This is a bit hacky, but try this in othermodule.py
:
import sys
def decorator(cls):
mod = __import__(cls.__module__)
mod.root = cls
Solution 2
That already works:
from othermodule import decorator
@decorator
class Someclass:
pass
Just put in othermodule.py
:
def decorator(cls):
#.... do something with cls
return cls
Solution 3
Having a decorator modify the global namespace if any module, let alone another module, is bad and never necessary. Code that mutates far-away globals is difficult to read and maintain. You should definitely consider modifying your design to avoid mutable global state and especially implicit assignment.
Author by
Doug W
Updated on June 03, 2022Comments
-
Doug W about 2 years
I want to use a function from another module as a decorator, but I need it to manipulate the current module's global namespace.
For example, I want to be able to go from this:
class SomeClass: pass root = SomeClass
to this:
from othermodule import decorator @decorator class Someclass: pass
Any ideas?
-
Doug W about 14 yearsYeah I know it works in general, but it's the fact that I want a decorator from the imported module to define a variable in the original module's global scope that causes trouble.
-
Doug W about 14 yearsYeah that worked, thanks. Actually I ended up using mod = sys.modules[cls.__module__] because the import call only returned the top level module (cls.__module__) was 4 levels deep - ie mod1.mod2.mod3.mod4
-
Marius Gedminas about 14 yearsIncidentally,
mod = __import__(cls.__module__, {}, {}, ('*', ))
would return the mod4 module, not the outermost mod1 package -
Mike Graham about 14 yearsThis is a direct answer (although error-prone for packages and such), but very scary code. Also, it's sort of silly to use
setattr
with string literals.setattr(foo, 'bar', baz)
is spelledfoo.bar = baz
. -
Duncan about 14 yearsYes, the setattr was excessive. I've removed it. The code isn't all that scary: module is a documented attribute of classes. Whether the OP should actually be doing it at all is of course another question.