2017-10-05 38 views
3

考虑以下几点:什么是传递给模块__init __()的隐式参数?

ParentModule.py

class ParentClass(): 
    def __init__(self): 
     pass 

ChildModule.py

class ChildClass(ParentClass): 
    def __init__(self): 
     pass 

如果在ChildModule,我错误地导入父模块,而不是父类,即:

import ParentModule 

而不是正确的

from ParentModule import ParentClass 

我会收到以下错误:

TypeError: module.__init__() takes at most 2 arguments (3 given) 

到底什么是传递到ParentModule's __init__()这3个参数隐? ParentModule.__init__()期望的2个参数是什么?

如何利用此功能?

+0

我无法重现。两个模块都在同一个目录中吗?我得到的唯一错误是:'NameError:name'ParentClass'未定义'。 –

+0

是的,'ParentClass'和'ParentModule'很可能在实际代码中有相同的名称,或者真正的代码有'class ChildClass(ParentModule)'而不是'class ChildClass(ParentClass)'。 – user2357112

+0

@ChristianDean:是的,真正的模块/类名称将是Parent.Parent和Child.Child,但我觉得使用该术语没有说明问题。如果你认为这样会更清楚,随意编辑这个问题。 –

回答

4

首先,错误信息有点误导,因为它忽略了隐含的self参数。它应该可能说takes at most 3 arguments (4 given),占self

如果你看一看的help输出模块类型:

>>> import sys 
>>> help(type(sys)) 

,你会看到以下内容:

Help on class module in module builtins: 

class module(object) 
| module(name[, doc]) 
| 
| Create a module object. 
| ... 

因此,模块式的__init__应该采取最多3个参数:self(未列出),name(模块名称)和可选的doc(文档字符串)。


这不是你通过它。当你误做

import ParentModule 

class ChildClass(ParentModule) 

Python的假设ParentModule是一个奇怪的元类的一类,并使用type(ParentModule)找一下应该是元类。它发现模块类型,并用3个参数调用它:名称('ChildClass'),基地((ParentModule,)),以及新类的字典你想创建:

type(ParentModule)('ChildClass', (ParentModule,), {'__init__': ..., ...}) 

这导致使用4个参数调用模块类型的__init__(在前面插入self),而模块类型的__init__不喜欢这样,所以会引发错误。


欲了解更多有关课程创作细节的信息,请参阅Python data model documentation on metaclasses

+0

出色的工作!我应该想过在模块对象上运行help()。 –

0

当您导入模块时,代码将在模块中加载__init__.py文件。 如果你想使用的init,例如预加载的模块,您可以添加代码为__init__.py

model/ 
    __init__.py 
    func1.py 
    func2.py