Найти - Пользователи
Полная версия: Нарушение разделения пространств имен при ООП
Начало » Python для новичков » Нарушение разделения пространств имен при ООП
1
streetmover
Доброго времени суток.
Есть такой код (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 не смешивал содержимое локальных переменных из разных методов?
4kpt_IV
streetmover
Теоретически, mc1 и mc2 - разные локальные переменные разных методов. И локальная переменная одного метода не должна быть видна другому методу

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

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

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

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

 def __init__(self, msglist=None):
        self.msglist = msglist or []
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB