Python: создание класса из базового класса внутри другого класса, созданного из базового класса - PullRequest
0 голосов
/ 03 октября 2018

В дальнейшем B является внешним классом, который наследуется от Bbase, а A является внутренним классом, который наследуется от Abase.

Я создаю B с переменной класса Bb = None, затем изменяю Bb Iзатем повторите процесс.В новом производном классе я обнаружил, что действительно Bb = None, поэтому я создал нетронутую копию класса B, что и было моим намерением.Пока все хорошо.

Также внутри B я создаю класс A с переменной класса Aa = None, и я тоже это изменяю.

Однако при повторении процессая подумал, что моя новая копия A имеет Aa равное ранее измененному значению, а не 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")

Кстати, если я создаю A вне B, тогдавставьте его в B через B.A = A, это даст желаемый эффект.Однако я надеялся создать его внутри B, как и другие объекты, принадлежащие классу B.

Разрешение

Во-первых, в результате этого обсуждения и обсуждения с коллегами по Hack Manhattan , я был разочарован серьезным заблуждением о том, как наследование работает в Python.Я думал, что такой вызов, как class Bbase(): pass; class B(Bbase): pass, создал новый класс B, а затем концептуально выполнил код из Bbase в B. Но на самом деле, концептуально, он просто копирует объекты в 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(), столько раз, сколько я хотел бы, и каждый раз я получаю нетронутый B, содержащий нетронутый A. Это своего рода обезьянье пятно, удерживающее обезьяну в клетке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...