3

我在 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

有没有办法做到这一点?

4

2 回答 2

5

是的,一点没错; 关键是模块本身就是对象。首先,您需要使MyClass子类成为模块类型:

from types import ModuleType

class MyClass(ModuleType):
    ...

然后用 MyClass 的实例替换当前模块:

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

请注意,这对于静态分析器和阅读您的代码的人来说可能会非常混乱。

于 2013-08-21T19:28:38.607 回答
0

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

"""
>>> 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)。

于 2013-08-21T19:44:53.197 回答