簡體   English   中英

當您固有於模塊而不是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM