繁体   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