模块可以像对象一样拥有属性吗?

新手上路,请多包涵

使用 python 属性,我可以做到这一点

obj.y

调用一个函数而不是仅仅返回一个值。

有没有办法用模块来做到这一点?我有一个我想要的案例

module.y

调用一个函数,而不仅仅是返回存储在那里的值。

原文由 Josh Gibson 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 683
1 个回答

由于 PEP 562 已在 Python >= 3.7 中实现,现在我们可以这样做

文件:module.py

 def __getattr__(name):
    if name == 'y':
        return 3
    raise AttributeError(f"module '{__name__}' has no attribute '{name}'")

other = 4

演示:

 >>> 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 None 的值。

编辑

我的回答不能有 setter 和 deleter。如果需要,采纳kxr的回答。

创建 <class 'module'> 的子类,在该类中定义属性,然后将模块类更改为该类。

文件: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

演示:

 >>> import mymodule
>>> mymodule.y
3
>>> mymodule.other
4
>>> mymodule.y = 5
>>> mymodule.y
5
>>> mymodule._y
5    # to prove that setter works

我太新手不知道它为什么有效。所以功劳应该归功于kxr。

原文由 John Lin 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题