![](/img/trans.png)
[英]What happens when I inherit from an instance instead of a class in Python?
[英]What happens when you inherent from a module instead of a class in Python?
我最近遇到了這個問題 。
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())
我收到此錯誤:
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'>
發生錯誤是因為Object是一個模塊,而不是一個類。 因此,您的繼承權很嚴格。
將您的導入語句更改為:
from Object import ClassName
和您的類定義為:
class Visitor(ClassName):
要么
將您的類定義更改為:
class Visitor(Object.ClassName): etc
我對這個答案不是很滿意,因為我不確定如何從錯誤消息中得出結論,即我是意外地從模塊而不是從類繼承的結論。 我想知道是否有人可以詳細說明為什么會發生此錯誤,以及給出的確切參數是什么? 當python解釋器遇到如下代碼時: class Employee(Person)
發生了什么事? 答對者的繼承權到底是什么意思? 感謝您對資源的任何解釋或引用。
如果將一個名為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
是普通類,則type(person)
將返回type
本身。 然后,將調用type.__init__
。
如果Person
是一個模塊,則type(person)
將返回對象module
,該對象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)
要弄清楚哪里出了問題,在這種情況下,您實際上無需查看錯誤消息,從代碼本身可以很清楚地看出來。
import foo
總是意味着foo是一個模塊(相對於from foo import bar
其中bar
可以是一個模塊,類,函數變量等)。 這是命名約定對我們有幫助的地方,如果PEP8
,則可以輕松區分類和模塊。 您問題中的代碼沒有遵循,這顯然不利於他人理解。
一旦獲得嘗試繼承/繼承module
的功能,剩下的就不那么棘手了。
大多數模塊沒有定義__init__
,這意味着當您嘗試訪問它時,它只是試圖在繼承鏈中找到它(如果您對此真的很感興趣,則可以閱讀python繼承,mro等內容,但是我懷疑這不是讓您感到困惑的原因。),然后找到了內置類module
(執行import Object;type(Object)
或import os; type(os)
)具有__init__
期望__init__
與您的重寫方法不同。 如果您的方法具有與上述參數完全相同的參數,則調試起來將更加棘手。
該錯誤消息似乎對您沒有幫助,因為python無法理解您是否有意覆蓋module.__init__
或某個類的__init__
。 嘗試
import os
help(type(os))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.