Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 16, 2017 13:06:22

streetmover
От:
Зарегистрирован: 2010-06-25
Сообщения: 25
Репутация: +  0  -
Профиль   Отправить e-mail  

Нарушение разделения пространств имен при ООП

Доброго времени суток.
Есть такой код (python 3.4, ОС - Windows-10):

 class MyClass():
    def __init__(self, msglist=[]):
        self.msglist = msglist
class Class_2():
    def method_1(self):
        mc1 = MyClass()
        mc1.msglist.append("append to mc1")
        print("mc1.msglist from method_1: ", str(mc1.msglist))
    def method_2(self):
        mc2 = MyClass()
        mc2.msglist.append("append to mc2")
        print("mc2.msglist from method_2: ", str(mc2.msglist))
if __name__ == '__main__':
    cls2 = Class_2()
    cls2.method_1()
    cls2.method_2()
На консоль он выводит следующее :
mc1.msglist from method_1: ('append to mc1')
mc2.msglist from method_2: ('append to mc1', ‘append to mc2’)
(на самом деле содержимое списков выводится в квадратных скобках, но квадратные скобки в сообщениях не пропускает движок форума, и это мелочи, не влияющие на суть вопроса)

Теоретически, mc1 и mc2 - разные локальные переменные разных методов. И локальная переменная одного метода не должна быть видна другому методу.
На практике же получается не так, то есть, нарушается принцип разделения пространства имен.

Вопросы:
1) Почему в локальной переменной mc2 из method_2() содержится то, что было добавлено в локальную переменную mc1 из метода method_1()?

2) Как сделать, чтобы python не смешивал содержимое локальных переменных из разных методов?



Офлайн

#2 Янв. 16, 2017 13:20:05

4kpt_IV
Зарегистрирован: 2016-01-08
Сообщения: 999
Репутация: +  49  -
Профиль   Отправить e-mail  

Нарушение разделения пространств имен при ООП

streetmover
Теоретически, mc1 и mc2 - разные локальные переменные разных методов. И локальная переменная одного метода не должна быть видна другому методу

В честь чего это? Это атрибуты класса. Это не локальные переменные. Локальные переменные без self.

Офлайн

#3 Янв. 16, 2017 13:31:16

Stright
От: Кострома
Зарегистрирован: 2015-01-20
Сообщения: 139
Репутация: +  16  -
Профиль   Отправить e-mail  

Нарушение разделения пространств имен при ООП

Это происходит потому, что в методе MyClass.__init__ вы используете изменяемый объект, как значение по-умолчанию для атрибута msglist. Поэтому в обоих экземплярах атрибут msglist ссылается на один и тот же список.

Подробнее

Отредактировано Stright (Янв. 16, 2017 13:33:34)

Офлайн

#4 Янв. 16, 2017 13:33:56

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2828
Репутация: +  185  -
Профиль   Отправить e-mail  

Нарушение разделения пространств имен при ООП

> Почему в локальной переменной mc2 из method_2() содержится то, что было добавлено в локальную переменную mc1 из метода method_1()?

Это ты попал в ловушку которая называется “изменяемый объект как значение по умолчанию”. Если ты пишешь def __init__(self, msglist, то у тебя словарь создаётся 1 раз при создании метода/функции. Т.к. он не переиздаётся, то в нём накапливаются все значения которые в него добавят, что у тебя собственно и происходит.

> 2) Как сделать, чтобы python не смешивал содержимое локальных переменных из разных методов?

 def __init__(self, msglist=None):
        self.msglist = msglist or []



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version