【问题标题】:Use alias for a property in Python at module level在模块级别为 Python 中的属性使用别名
【发布时间】:2013-08-21 19:07:45
【问题描述】:

我在 Python 2.7 中有以下内容:

class MyClass(object):
    ...
    @property
    def my_attr(self):
        ...

    @my_attr.setter
    def my_attr(self, value):
        ...

我使用 getter/setter 以便我可以在那里做一些逻辑。

那我可以打电话了:

import myModule
test = myModule.MyClass()
test.my_attr = 9

我想在模块级别使用别名,这样我就可以做类似的事情:

import myModule
myModule.my_attr = 9

有没有办法做到这一点?

【问题讨论】:

  • 这到底能做什么?
  • 我只是想简化我的库的使用。例如,我不想让 myPackage.myModule.myClass.test = 9,而是让 myPackage.myModule.test = 9。

标签: python python-2.7


【解决方案1】:

是的,绝对的;关键是模块本身就是对象。首先,您需要将 MyClass 子类化为模块类型:

from types import ModuleType

class MyClass(ModuleType):
    ...

然后你替换当前模块为 MyClass 的一个实例:

import sys
sys.modules[__name__] = MyClass(__name__)

请注意,这可能会让静态分析器和阅读您的代码的人感到非常困惑。

【讨论】:

  • 这似乎行得通。但是如果我想追加到模块而不是替换呢?
  • @MasterMind 之类的 self.__dict__.update(real_module.__dict__) 应该可以工作。或者您可以将 self.__dict__ 替换为 collections.ChainMap(自 3.3 起)。
  • 请注意,在执行此操作时必须小心——请参阅this question 接受的答案。
【解决方案2】:

要为模块的某些属性提供特殊处理,您可以定义一个代理类来执行特殊处理并将其余部分委托给原始模块对象:

"""
>>> import property_on_module
>>> property_on_module.attr = 1
set attr property
>>> property_on_module.attr
get attr property
1
"""
import sys

class Module(object):
    def __init__(self, module):
        self.__module = module

    def __getattr__(self, name):
        return getattr(self.__module, name)

    @property
    def attr(self):
        print("get attr property")
        return self.__attr

    @attr.setter
    def attr(self, value):
        print("set attr property")
        self.__attr = value

if __name__ == "__main__": # test if run as a script
    import doctest
    sys.exit(doctest.testmod().failed)
else: # normal import, use `Module` class to provide `attr` property
    sys.modules[__name__] = Module(sys.modules[__name__])

__getattr__ 可能还不够;在这种情况下,您可以定义__getattribute__/__setattr__,例如quickdraw.py(基于sh.py)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    相关资源
    最近更新 更多