Can modules have properties the same way that objects can?
Only instances of new-style classes can have properties. You can make Python believe such an instance is a module by stashing it in sys.modules[thename] = theinstance
. So, for example, your m.py module file could be:
import sysclass _M(object): def __init__(self): self.c = 0 def afunction(self): self.c += 1 return self.c y = property(afunction)sys.modules[__name__] = _M()
I would do this in order to properly inherit all the attributes of a module, and be correctly identified by isinstance()
import typesclass MyModule(types.ModuleType): @property def y(self): return 5>>> a=MyModule("test")>>> a<module 'test' (built-in)>>>> a.y5
And then you can insert this into sys.modules:
sys.modules[__name__] = MyModule(__name__) # remember to instantiate the class
As PEP 562 has been implemented in Python >= 3.7, now we can do this
file: module.py
def __getattr__(name): if name == 'y': return 3 raise AttributeError(f"module '{__name__}' has no attribute '{name}'")other = 4
usage:
>>> import module>>> module.y3>>> module.other4>>> module.nosuchTraceback (most recent call last): File "<stdin>", line 1, in <module> File "module.py", line 4, in __getattr__ raise AttributeError(f"module '{__name__}' has no attribute '{name}'")AttributeError: module 'module' has no attribute 'nosuch'
Note that if you omit the raise AttributeError
in the __getattr__
function, it means the function ends with return None
, then the module.nosuch
will get a value of None
.