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

时间:2018-10-03 04:27:08

标签: python python-3.x inheritance nested

在下面,B是从Bbase继承的外部类,而A是从Abase继承的内部类。

我用类变量B.b = None创建B,然后更改B.b。然后,我重复该过程。在新的派生类中,我发现确实B.b = None,所以我创建了B类的原始副本,这是我的意图。到目前为止,一切都很好。

同样在B中,我创建了一个具有类变量A.a = None的类A,我也对此进行了更改。

但是,在该过程的重复中,我认为我的A的新副本原来具有等于先前更改的值的A.a,而不是我从基类的初始化程序中期望的None。就是说,我毕竟还没有收到过原始的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之外创建A,然后通过B.A = A将其插入B中,则将达到预期的效果。不过,我希望像在B类中的其他对象一样,在B中创建它。

解决方案

首先,由于进行了这次讨论并与Hack Manhattan的同事进行了跟进,我对关于继承在Python中的工作方式的严重误解感到失望。我以为,像class Bbase(): pass; class B(Bbase): pass这样的调用创建了一个新的类B,然后从概念上讲,从Bbase中的代码执行了B。但是实际上,从概念上讲,它只是将对象复制到在创建Bbase时创建的对象中。 。那是我的啊哈!时刻。也许其他人会发现这很有用。 (请注意,最后的解释也是错误的。请参见下面与user2357112的讨论。)

第二,以下方法效果很好:

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。这有点像猴子的补丁,将猴子保持在笼子里。

0 个答案:

没有答案