当您从模块而不是 Python 中的 class 继承时会发生什么?
What happens when you inherent from a module instead of a class in Python?
我最近遇到了 this question。
import Object
class Visitor(Object):
def __init__(self):
super(Visitor,self).__init__()
def visit(self, obj):
pass
def getIsDone(self):
return False
isDone = property(fget =lambda self:self.getIsDone())
I get this error:
TypeError: module.__init__() takes at most 2 arguments (3 given)
及其答案:
class A:pass
print(A) #outputs <class '__main__.A'>
import urllib
print(urllib) #outputs <module 'urllib' from '/usr/lib/python3.2/urllib/__init__.py'>
Your error is happening because Object is a module, not a class. So
your inheritance is screwy.
Change your import statement to:
from Object import ClassName
and your class definition to:
class Visitor(ClassName):
or
change your class definition to:
class Visitor(Object.ClassName):
etc
我对这个答案不是很满意,因为我不太确定我是如何从该错误消息中得出我不小心从模块而不是 class 继承的结论的。我想知道是否有人可以详细说明为什么会发生此错误以及给出的参数到底是什么?当 python 解释器遇到这样的代码时:
class Employee(Person)
发生了什么事?回答者所说的我的继承是古怪的到底是什么意思?感谢您对资源的任何解释或引用。
要找出你哪里出错了,在这种情况下你真的不需要看错误信息,从代码本身就很清楚了。
import foo
总是意味着 foo 是一个模块(与 from foo import bar
相反,其中 bar
可以是一个模块,class,函数是一个变量等等)。这是命名约定帮助我们的地方,如果遵循 PEP8
,那么可以很容易地区分 classes 和模块。你问题中的代码不遵循这显然不利于其他人理解。
一旦你知道你已经尝试 subclass/inherit 一个 module
剩下的就不是那么棘手了。
大多数模块没有定义 __init__
这意味着当你试图访问它时,它只是试图在继承链中找到它(如果你真的对此感兴趣,你可以阅读 python 继承、mro 等,但我怀疑这不是让你在这里感到困惑的原因。)并找到内置的 class module
其中(执行 import Object;type(Object)
或 import os; type(os)
) 有一个 __init__
期望与您重写的方法不同的参数。如果您的方法具有与上面完全相同数量的参数,那么调试起来会更加棘手。
该错误消息似乎对您没有帮助,因为 python 无法理解您是有意覆盖 module.__init__
还是某些 class 的 __init__
。尝试
import os
help(type(os))
如果你把一个叫做BaseClass
的对象放在继承列表中,那么解释器会在内部调用它:
type(BaseClass).__init__(cls, name_of_subclass, (BaseClass,), dict_of_subclass)
# or simpler
type(BaseClass)(name_of_subclass, (BaseClass,), dict_of_subclass)
您可以创建一个虚拟 BaseClass 来测试它
class Meta(object):
def __init__(self, name, base, subcls):
print (self, name, base, subcls)
Base = Meta('','','')
class Test(Base):
prop1="hello"
输出:
<__main__.Meta object at 0x7f7471666bd0>
<__main__.Meta object at 0x7f7471666c50> Test (<__main__.Meta object at 0x7f7471666bd0>,) {'__module__': '__main__', 'prop1': 'hello'}
回答你的问题:当解释器看到class Employee(Person): pass
时,会发生以下情况:
type(Person).__init__(cls, 'Employee', (Person,), {'__module__': '__main__'})
如果 Person
是正常的 class,type(person)
将 return type
本身。然后 type.__init__
会被调用。
如果 Person
是一个模块,type(person)
将 return 对象 module
,它有一个方法 __init__
。但是这个方法只需要2个参数,你会得到一个错误。
import sys
type(sys).__init__(sys,2,3,4)
#Traceback (most recent call last):
# File "testClassInheritance.py", line 11, in <module>
# type(sys).__init__(sys,2,3,4)
#TypeError: module.__init__() takes at most 2 arguments (3 given)
我最近遇到了 this question。
import Object class Visitor(Object): def __init__(self): super(Visitor,self).__init__() def visit(self, obj): pass def getIsDone(self): return False isDone = property(fget =lambda self:self.getIsDone())
I get this error:
TypeError: module.__init__() takes at most 2 arguments (3 given)
及其答案:
class A:pass print(A) #outputs <class '__main__.A'> import urllib print(urllib) #outputs <module 'urllib' from '/usr/lib/python3.2/urllib/__init__.py'>
Your error is happening because Object is a module, not a class. So your inheritance is screwy.
Change your import statement to:
from Object import ClassName
and your class definition to:
class Visitor(ClassName):
or
change your class definition to:
class Visitor(Object.ClassName): etc
我对这个答案不是很满意,因为我不太确定我是如何从该错误消息中得出我不小心从模块而不是 class 继承的结论的。我想知道是否有人可以详细说明为什么会发生此错误以及给出的参数到底是什么?当 python 解释器遇到这样的代码时:
class Employee(Person)
发生了什么事?回答者所说的我的继承是古怪的到底是什么意思?感谢您对资源的任何解释或引用。
要找出你哪里出错了,在这种情况下你真的不需要看错误信息,从代码本身就很清楚了。
import foo
总是意味着 foo 是一个模块(与 from foo import bar
相反,其中 bar
可以是一个模块,class,函数是一个变量等等)。这是命名约定帮助我们的地方,如果遵循 PEP8
,那么可以很容易地区分 classes 和模块。你问题中的代码不遵循这显然不利于其他人理解。
一旦你知道你已经尝试 subclass/inherit 一个 module
剩下的就不是那么棘手了。
大多数模块没有定义 __init__
这意味着当你试图访问它时,它只是试图在继承链中找到它(如果你真的对此感兴趣,你可以阅读 python 继承、mro 等,但我怀疑这不是让你在这里感到困惑的原因。)并找到内置的 class module
其中(执行 import Object;type(Object)
或 import os; type(os)
) 有一个 __init__
期望与您重写的方法不同的参数。如果您的方法具有与上面完全相同数量的参数,那么调试起来会更加棘手。
该错误消息似乎对您没有帮助,因为 python 无法理解您是有意覆盖 module.__init__
还是某些 class 的 __init__
。尝试
import os
help(type(os))
如果你把一个叫做BaseClass
的对象放在继承列表中,那么解释器会在内部调用它:
type(BaseClass).__init__(cls, name_of_subclass, (BaseClass,), dict_of_subclass)
# or simpler
type(BaseClass)(name_of_subclass, (BaseClass,), dict_of_subclass)
您可以创建一个虚拟 BaseClass 来测试它
class Meta(object):
def __init__(self, name, base, subcls):
print (self, name, base, subcls)
Base = Meta('','','')
class Test(Base):
prop1="hello"
输出:
<__main__.Meta object at 0x7f7471666bd0>
<__main__.Meta object at 0x7f7471666c50> Test (<__main__.Meta object at 0x7f7471666bd0>,) {'__module__': '__main__', 'prop1': 'hello'}
回答你的问题:当解释器看到class Employee(Person): pass
时,会发生以下情况:
type(Person).__init__(cls, 'Employee', (Person,), {'__module__': '__main__'})
如果 Person
是正常的 class,type(person)
将 return type
本身。然后 type.__init__
会被调用。
如果 Person
是一个模块,type(person)
将 return 对象 module
,它有一个方法 __init__
。但是这个方法只需要2个参数,你会得到一个错误。
import sys
type(sys).__init__(sys,2,3,4)
#Traceback (most recent call last):
# File "testClassInheritance.py", line 11, in <module>
# type(sys).__init__(sys,2,3,4)
#TypeError: module.__init__() takes at most 2 arguments (3 given)