Совместное использование переменных класса в наследовании Python - PullRequest
0 голосов
/ 30 апреля 2018

Я запутался с концепцией разделения переменных в Python в наследовании.

Рассмотрим следующий код: -

class a(object):
    var1 = 0
    var2 = {}
    def print_var(self):
        print(self.var1)
        print(self.var2)

class b(a):
    @classmethod
    def modify_var(cls):
        cls.var1 = 1
        cls.var2['temp']="something"

o1 = a()
o2 = b()
print("Initial Values")
o1.print_var()
o2.print_var()
print("Changing Values")
o2.modify_var()
print("Print values after change")
o1.print_var()
o2.print_var()

После выполнения кода выше я вижу, что словарь распределяется между дочерним и родительским классом, но целочисленная переменная не является.

Кто-нибудь может объяснить, пожалуйста, или что я здесь не так делаю?

Вывод вышеуказанного кода:

Initial Values
0
{}
0
{}
Changing Values
Print values after change
0    # <- this zero should be one according to my understanding
{'temp': 'something'}
1
{'temp': 'something'}

1 Ответ

0 голосов
/ 30 апреля 2018

Как правило, вы не хотите использовать изменяемые переменные класса. Переменная класса является общей ссылкой на объект для всех экземпляров класса. Но он не распространяется на унаследованные классы.

Таким образом, все экземпляры a совместно используют ссылки на объекты a.var1 и a.var2. Аналогично, все экземпляры b совместно используют ссылки на объекты на b.var1 и b.var2. После создания наследования b также получает ссылки на var1 и var2, но они не передаются обратно a или любым экземплярам a.

Поскольку вы используете изменяемый объект для var2, ссылка на объект никогда не изменяется после наследования. Таким образом, вы можете изменить var2, и он будет изменен для всех ссылок на него, потому что ссылка на объект одинакова.

Если вы измените var2 вместо его изменения, вы получите ожидаемое поведение.

Попробуйте это:

class a(object):
    var1 = 0
    var2 = {}
    def print_var(self):
        print(self.var1, end=', ')
        print(self.var2)

class b(a):
    @classmethod
    def modify_var(cls):
        cls.var1 = 1
        cls.var2 = {'temp': 'something'}  # reassign to a new dict

Вот несколько тестов:

ob1 = a()
ob2 = b()

o1.print_var()
o2.print_var()

o2.modify_var()

o1.print_var()
o2.print_var()

# prints
0, {}
0, {}
0, {}
1, {'temp': 'something'}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...