python - 当我从 Python 中的实例而不是类继承时会发生什么?

标签 python class inheritance instance

我只是好奇当我将一个实例继承到一个类中时会发生什么。

所以我尝试了:

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

我只是想知道:继承一个实例是有意义/有用的还是纯粹的废话?

(这个问题有点学术性,特别是关于继承实例的细节。它与对象委托(delegate)或一般设计实践等替代方案无关。)

最佳答案

类就像实例;他们有一个类型。对于类型是类的实例,但对于类,类型称为元类。从一个类继承通常会调用基类的元类型来生成一个新的类对象(使用 type(base) ;适用于多个基类限制)。标准元类型是 type对象,但你可以 create your own metaclasses .

通过从实例继承,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 的其他部分期望存在的类的属性。您的类(class)必须涵盖所有这些;在上面的示例输出中,您会注意到 repr(Child)生产 <__main__.X object at 0x...>而不是预期的 <class '__main__.Child'> , 并且没有 __call__为类生成实例的方法。因此,使用一个实例作为另一个实例的基类可以工作,您只需要付出额外的工作来定义所有预期的功能。

最后,使用实例作为基类是可能的,但没有实际用途,而不是在任何用例已经被元类覆盖的情况下。

关于python - 当我从 Python 中的实例而不是类继承时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42361222/

相关文章:

python - 在 Amazon AWS 中运行 Selenium 文件

python - 当 LSTM 层的输入数量大于或小于该层中 LSTM 单元的数量时,Keras 会做什么?

python - 未实现错误: Operator 'getitem' is not supported on this expression

c++ - CUDA 矩阵类的 operator() 重载

c++ - vector<unique_ptr> 的初始化因复制错误而失败

javascript - 了解主干扩展

c# - EF继承和主键

python - 递归阶乘计算器 RecursionError

java - 使用 "add"方法将对象从单独的类添加到 ArrayList

php - 不在对象上下文中时使用 $this