Can modules have properties the same way that objects can?
properties, python, python-module
Solution
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
demo:
>>> import module
>>> module.y
3
>>> module.other
4
>>> module.nosuch
Traceback (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`.
EDIT
My answer cannot have setters and deleters. If you need, adopt kxr's answer.
Create a subclass of `<class 'module'>`, define properties in that class, then change module class into that class.
file: mymodule.py
import sys
class This(sys.__class__): # sys.__class__ is <class 'module'>
_y = 3
@property
def y(self): # do the property things in this class
return self._y
@y.setter
def y(self, value): # setter is also OK
self._y = value
other = 4
sys.modules[__name__].__class__ = This # change module class into This
demo:
>>> import mymodule
>>> mymodule.y
3
>>> mymodule.other
4
>>> mymodule.y = 5
>>> mymodule.y
5
>>> mymodule._y
5 # to prove that setter works
I am too novice to know why it works. So the credit should go to kxr.
Problem
With python properties, I can make it such that ``` obj.y ``` calls a function rather than just returning a value. Is there a way to do this with modules? I have a case where I want ``` module.y ``` to call a function, rather than just returning the value stored there.