模块的属性是否与对象可以相同?

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

obj.y 

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

有没有办法做到这一点与模块? 我有我想要的情况

 module.y 

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

只有新风格类的实例可以有属性。 你可以让Python相信这样一个实例是一个模块,通过在sys.modules[thename] = theinstance隐藏它。 因此,例如,您的m.py模块文件可能是:

 import sys class _M(object): def __init__(self): self.c = 0 def afunction(self): self.c += 1 return self.c y = property(afunction) sys.modules[__name__] = _M() 

编辑 :删除了对全局variables的隐式依赖(与示例点没有任何关系,但是通过使原始代码失败而混淆了事物)。

我会这样做,以便正确地inheritance模块的所有属性,并通过isinstance()正确识别

 import types class MyModule(types.ModuleType): @property def y(self): return 5 >>> a=MyModule("test") >>> a <module 'test' (built-in)> >>> ay 5 

然后你可以插入到sys.modules中:

 sys.modules[__name__] = MyModule(__name__) # remember to instantiate the claas 

一个典型的用例是:用一些(很less)dynamic属性来丰富一个(巨大的)现有模块,而不用把所有的模块东西变成一个类的布局。 不幸的是,像sys.modules[__name__].__class__ = MyPropertyModule这样的最简单的模块类补丁会失败,并且TypeError: __class__ assignment: only for heap types失败TypeError: __class__ assignment: only for heap types sys.modules[__name__].__class__ = MyPropertyModule TypeError: __class__ assignment: only for heap types 。 所以模块创build需要重新布线。

这种方法没有Python导入钩子,只是在模块代码的顶部有一些序言:

 # propertymodule.py """ Module property example """ if '__orgmod__' not in globals(): # constant prolog for having module properties / supports reload() print "PropertyModule stub execution", __name__ import sys, types class PropertyModule(types.ModuleType): def __str__(self): return "<PropertyModule %r from %r>" % (self.__name__, self.__file__) modnew = PropertyModule(__name__, __doc__) modnew.__modclass__ = PropertyModule modnew.__file__ = __file__ modnew.__orgmod__ = sys.modules[__name__] sys.modules[__name__] = modnew exec sys._getframe().f_code in modnew.__dict__ else: # normal module code (usually vast) .. print "regular module execution" a = 7 def get_dynval(module): return "property function returns %s in module %r" % (a * 4, module.__name__) __modclass__.dynval = property(get_dynval) 

用法:

 >>> import propertymodule PropertyModule stub execution propertymodule regular module execution >>> propertymodule.dynval "property function returns 28 in module 'propertymodule'" >>> reload(propertymodule) # AFTER EDITS regular module execution <module 'propertymodule' from 'propertymodule.pyc'> >>> propertymodule.dynval "property function returns 36 in module 'propertymodule'" 

注意:类似于from propertymodule import dynval东西会产生一个当然的冻结副本 – 对应于dynval = someobject.dynval