Python:在从基类创建的另一个类中从基类创建类

2024-10-05 17:39:19 发布

您现在位置:Python中文网/ 问答频道 /正文

在下面的例子中,B是从Bbase继承的外部类,A是从Abase继承的内部类。你知道吗

我用类变量B.B=None创建B,然后修改B.B,然后重复这个过程。在新的派生类中,我发现确实B.B=None,所以我创建了一个B类的原始复制,这是我的意图。到目前为止,还不错。你知道吗

同样在B中,我用类变量a.a=None创建了一个类a,并对其进行了修改。你知道吗

然而,在这个过程的重复中,我认为是A的新复制结果是A.A等于先前修改过的值,而不是我所期望的基类中的初始值。也就是说,我并没有收到a的原始复制品,而是我的B复制品包含了我之前创建的相同的类a(或者可能是具有相同修改的副本)。下面的代码和输出显示了这一点。你知道吗

实际上,我希望我的B的原始复制品包含a的原始复制品,而不是之前修改过的a的原始复制品?你知道吗

代码:

class Abase():
    a = None

class Bbase():
    b = None
    class A(Abase): pass

print('Run 1')
class B(Bbase): pass
print('B.b, B.A.a=', B.b, B.A.a, '(Expect "None None")')
B.b = 23
B.A.a = 47
print('B.b, B.A.a=', B.b, B.A.a, '(Expect "23 47")')
print()

print('Run 2')
class B(Bbase): pass
print('B.b, B.A.a=', B.b, B.A.a, '(Expect "None None")')
B.b = 23
B.A.a = 47
print('B.b, B.A.a=', B.b, B.A.a, '(Expect "23 47")')

输出(Python 3.7.0、MacOS 10.13.6):

Run 1
B.b, B.A.a= None None (Expect "None None")
B.b, B.A.a= 23 47 (Expect "23 47")

Run 2
B.b, B.A.a= None 47 (Expect "None None") <====
B.b, B.A.a= 23 47 (Expect "23 47")

顺便说一下,如果我在B的外部创建一个,然后通过B.A = A将它插入到B中,这就达到了预期的效果。不过,我希望在B中创建它,就像其他属于B类的对象一样

分辨率

首先,通过这次讨论以及与Hack Manhattan同事的后续讨论,我对Python中继承的工作原理产生了严重的误解。我原以为像class Bbase(): pass; class B(Bbase): pass这样的调用创建了一个新的类B,然后在概念上执行B中Bbase的代码。但实际上,在概念上,它只是将Bbase创建时创建的对象复制到B中。那是我的啊哈!时刻。也许其他人会觉得这很有用。(注意最后的解释也是错误的。参见下面与用户2357112的讨论。)

其次,以下几点很有效:

class Abase():
    a = None

class Bbase():
    b = None
    @classmethod
    def getA(cls):
        class A(Abase): pass
        cls.A = A

然后,我可以重复像class B(Bbase): pass; B.getA()这样的调用任意多次,每次我都会得到一个包含原始a的原始B。这是一种猴子补丁,把猴子关在笼子里。你知道吗


Tags: 对象run代码none概念过程passclass