Python __在模块内定义的初始化、新建等

Python __在模块内定义的初始化、新建等,python,Python,我知道,当从foo导入栏导入一个模块时,或者即使导入该模块中的特定对象,也会首先计算整个模块。但我只是好奇,如果我们在这个模块中定义一个_uinit_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu或一个uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?为什么会这样?不。有一个模块类,模块是这个类的实例,但它是Python内部的。在模块中定义魔术方法不会将它们添加到模块类中,并且在导入时也不会执行任何特殊操作。简单地说,模块没有方法

我知道,当从foo导入栏导入一个模块时,或者即使导入该模块中的特定对象,也会首先计算整个模块。但我只是好奇,如果我们在这个模块中定义一个_uinit_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu或一个uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?为什么会这样?

不。有一个模块类,模块是这个类的实例,但它是Python内部的。在模块中定义魔术方法不会将它们添加到模块类中,并且在导入时也不会执行任何特殊操作。

简单地说,模块没有方法

更严格地说,每个模块都是某个类的实例,通常是builtins.module,尽管您可以用导入钩子或monkeypatching替换它,而且该类当然有方法。但是模块的全局函数不是模块对象的方法

只需打印出typefoo.func,就可以很容易地验证这一点。它是一个函数,而不是foo实例的绑定方法

最重要的是,即使模块全局函数是实例方法,也不会有任何区别,因为u_init_uuu是在类字典中检查的,而不是在实例字典中检查的。如果您仔细想想,就不可能有其他情况,因为在uu init_uu返回之前,您没有要检查的实例字典。因此,只有当每个模块都是一个类对象和类型的实例时,这才可能起作用,而它们显然不是

你对init.py的混淆是在转移注意力。文件不是函数,更不是方法,文件和模块都不能调用

如果需要严格的定义:定义类和模块。正如您所看到的,新方法是类特有的特性。定义了它的行为。注意uuu init uuu实际上是作为object的结果调用的。uuu new uuuu,所以它甚至没有为类定义技术性的定义,但它肯定没有为其他任何东西定义

同时,定义了uu init uuu.py。请注意,在Python3.2中,这只是默认导入程序对常规包使用的约定,而不是语言本身的一部分


除了命名和一些模糊的相似之处,这两个特征没有任何共同之处。也许命名是一个错误,但我认为更多的人从命名中得到有用的直觉,而不是困惑。无论如何,因为它回到了Python 1.3的ni模块,我怀疑它是否会很快被改变。

我认为你可以通过做一些类似于我在回答不相关问题时所做的事情来创建一个在包中没有任何意义的类。@abarnert我们确实有一个"初始化"和"新"函数。是的,“但那不是一个函数,也不是一个方法。”abarnert补充道。但它会被执行。类似于函数调用?不同的语义我猜它和函数调用不是很相似。模块包含在第一次导入时执行的代码,即在计算模块定义时执行一次。函数包含的代码在计算函数定义时不会执行,而是在以后每次调用结果函数时执行。模块不是可调用的,如果在交互提示下键入sys,您会立即看到。这有点误导。这里的关键点是,模块中的全局函数不是模块对象的方法。如果您确实在模块类中定义了_uinit_uuuuuuuu和_uunew_uuuuuuuuu方法,或者更确切地说,在导入hook或monkeypatch的子类中定义了_uuuinit_uuuuuuuuu方法,那么它们就可以工作了。那么为什么对包的处理会有所不同?指的是uuu init uuuuu。py@hus787当前位置没有区别对待他们。谁说他们是?@abarnert导入包时,会执行_uinit__u;.py。但在模块内部,不会调用/执行init。因此,根据观察结果,似乎有所不同。_init__;py只是与_init__;方法同名。然而,文件不是一种方法,因此不应该有任何混淆。