簡體   English   中英

當我從Python中繼承實例而不是類時會發生什么?

[英]What happens when I inherit from an instance instead of a class in Python?

我只是好奇當我將一個實例繼承到一個類時會發生什么。

所以我嘗試過:

class X:
    def __init__(self, x):
        self.x = x
    def print(self):
        print(self.x)

def inherit(obj):
    class Child(obj): # Line 20
        pass  # or maybe added functionality

    return Child

param = 5
x = X(param)
y = inherit(x) # Line 27
y.print()

我得到(至少)以下錯誤:

Traceback (most recent call last):
  File "/test.py", line 27, in <module>
    y = inherit(x)
  File "/test.py", line 20, in inherit
    class Child(obj):
TypeError: __init__() takes 2 positional arguments but 4 were given

我只是想知道: 繼承一個有意義/有用的實例還是簡單的廢話?

(這個問題有點學術性,特別是關於繼承實例的細節。它不是關於對象委托或一般設計實踐等替代方案。)

類就像實例一樣; 他們有一個類型 對於類型是類的實例,但對於類,類型稱為元類 從類繼承通常會調用基類的元類型來生成一個新的類對象(使用type(base) ;對於多個type(base)限制適用)。 標准元typetype對象,但您可以創建自己的元類

通過繼承實例,Python嘗試通過調用type(obj)(classname, bases, body_namespace)來創建一個新類。 由於type(obj)XX.__init__()不支持這些參數,因此調用失敗。 但是,沒有什么可以阻止你使這部分工作!

>>> class X:
...     def __init__(self, classname, parents, namespace):
...         print('Creating {}{}'.format(classname, parents))
...
>>> class Child(X('X', (), {})): pass
...
Creating X()
Creating Child(<__main__.X object at 0x10372b4a8>,)
>>> Child
<__main__.X object at 0x10372b470>
>>> Child()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'X' object is not callable

當然, type提供了更多的功能,類不會開箱即用; 有一系列描述符可以提供Python的其他部分期望存在的類的屬性。 你的班級必須覆蓋所有這些; 在上面的示例輸出中,您將注意到repr(Child) <__main__.X object at 0x...>生成<__main__.X object at 0x...>而不是預期的<class '__main__.Child'> ,並且沒有__call__方法來生成實例班級。 因此,使用實例作為另一個實例的基類可以工作,您只需要額外的工作來定義所有預期的功能。

最后,使用實例作為基類是可能的,但是沒有實際用途,而不是當任何用例已經由元類覆蓋時。

在引擎蓋下,Python有一個基於原型的面向對象設計模型。 這意味着所有東西,甚至是類,都是Pythonic世界中的對象。 https://en.wikipedia.org/wiki/Prototype-based_programming

Python中的繼承關系是通過引用其類的實例中的引用來執行的。 這是課堂 您可以在運行時將此引用更改為任何其他類。 如果您這樣做是為了在運行時更改實例的行為,那么您正在實現動態繼承。 例如,考慮一個元素列表的實例,即ListOfOne類,它具有僅處理一個元素的適當方法。 如果添加了另一個元素,則引用可以更改為RegularList 如果列表已清空,則其類可以更改為EmptyList

不幸的是(或不是)Python隱藏了所有這些。 例如,您在類標簽下創建原型,並禁止在此視圖下完全合法的一些操作。 因此,可以從實例繼承,但Python否認了這種可能性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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