2013-08-21 42 views
1

我見在Python 2.7以下:Python中使用屬性別名在模塊級

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 

有沒有辦法做到這一點?

+0

那會怎樣呢? –

+0

我只是想簡化我的圖書館的使用。例如,而不是myPackage.myModule.myClass.test = 9,我想做myPackage.myModule.test = 9。 – MasterMind

回答

3

是的,絕對;關鍵是模塊本身就是對象。首先,你需要做MyClass子模塊類型:

from types import ModuleType 

class MyClass(ModuleType): 
    ... 

然後你更換當前模塊MyClass的實例:

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

注意,這可能是相當混亂的靜態分析儀和給閱讀你的代碼的人。

+0

這似乎工作。但是如果我想要_append_到模塊而不是_replacing_呢? – MasterMind

+0

@MasterMind類似於'self .__ dict __。update(real_module .__ dict __)'應該有效。或者你可以用'collections.ChainMap'替換'self .__ dict__'(自3.3開始)。 – ecatmur

+0

請注意,這樣做時必須小心 - 請參閱[此問題]的接受答案(http://stackoverflow.com/questions/5365562/why-is-the-value-of-name-changing-after-分配到SYS模塊名稱)。 – martineau

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