繁体   English   中英

sys.modules[__name__] = _classname()。 它实际上是做什么的?

[英]sys.modules[__name__] = _classname(). What does it actually do?

我正在阅读这个问题中提到的 Alex Martelli 的这段代码 我知道sys.modules[__name__]告诉你你当前所在的模块,但是他的constant.py末尾的这行代码真的让我很困惑。 在文件末尾声明当前模块的语句有什么意义和意义?

# Put in const.py...:
class _const:
    class ConstError(TypeError): pass
    def __setattr__(self,name,value):
        if self.__dict__.has_key(name):
            raise self.ConstError, "Can't rebind const(%s)"%name
        self.__dict__[name]=value
import sys
sys.modules[__name__]=_const() #this I don't understand
# that's all -- now any client-code can
import const

基本上,我的问题是,在我看来,这行代码没有做任何事情。 我理解错了吗? 由于在 Python 中您不必将类定义放在单独的文件中,因此我认为我并不真正需要两个模块,除非我想重用“const”类。 那么在这种情况下sys.moldules[__name__]=_const()也不是必需的......我理解正确吗?

我相信它将实例绑定到模块。 因此,当您执行import const时,您实际上获得了_const类的实例。

这允许您在其上调用方法。 例如, __setattr__ ,在这种情况下,它会检查您是否只绑定了一次变量。

Guido van Rossum 将其描述为有时推荐的hack

https://mail.python.org/pipermail/python-ideas/2012-May/014969.html

# foo.py
import sys

class Foo:
    def funct1(self, <args>): <code>
    def funct2(self, <args>): <code>

sys.modules[__name__] = Foo()

这是有效的,因为导入机制正在积极地启用这个 hack,并且作为它的最后一步,在加载后将实际模块从 sys.modules 中拉出。 (这绝非偶然。该 hack 是很久以前提出的,我们决定我们很喜欢在进口机器中支持它。)

您可以通过这种方式轻松覆盖__getattr__ / __getattribute__ / __setattr__ 它还使模块的“子类化”变得更容易一些(尽管访问要用作基类的类有点棘手:您必须使用foo.__class__ )。 但当然,Greg 所抱怨的那种 API 永远不会以这种方式实现,所以那是相当无用的。 而且,如果您从一开始就将模块设计为可继承的类,则最好只使用类而不是上述技巧。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM