Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 11, 2019 03:58:37

W.Thesis
Зарегистрирован: 2019-08-11
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

"разделяемый" между различными объекта член класса

Случайно наткнулся.

 class test:
    a = []
    def __init__(self, x)
        self.a.append(x)
foo = test(1)
bar = test(5)
И после этого и foo.a и bar.a оба равны списку из 1 и 5
Какого … ? Почему .a оказался разделяемым, общим?
И это только для списка.
Член класса целого типа не оказывается общим для двух разных объектов.

Офлайн

#2 Авг. 11, 2019 04:34:22

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10024
Репутация: +  857  -
Профиль   Отправить e-mail  

"разделяемый" между различными объекта член класса

W.Thesis
Какого … ? Почему .a оказался разделяемым, общим?
Потому что это переменная класса, а не переменная экземпляра.
  
>>> class A:
...     def __init__(self, x):
...         self.a = []
...         self.a.append(x)
... 
>>> a1 = A(1)
>>> a2 = A(2)
>>> 
>>> a1.a
[1]
>>> a2.a
[2]
>>>

В классе ты определяешь переменные, которые должны быть во всех экземплярах одинаковыми. А вот в экземплярах ты определяешь переменные, которые должны быть уникальными в пределах экземпляра.



Отредактировано py.user.next (Авг. 11, 2019 04:38:56)

Офлайн

#3 Авг. 11, 2019 12:39:47

W.Thesis
Зарегистрирован: 2019-08-11
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

"разделяемый" между различными объекта член класса

py.user.next
Потому что это переменная класса, а не переменная экземпляра.

Вот это новость!
Класс является описателем для (в том числе) переменных, которыми будет наделён экземпляр. Класс - чертёж, объект - изделие. Понятия “член класса” и “свойство объекта” в прочих ООП-языках почти эквивалентны, за малой разницей того, что “член класса” упоминается в связи с его типом, а “свойство объекта” - со значением.

Да, можно сделать такой проп, который будет единственным и разделяемым для всех экземпляров класса, но это требует дополнительных мер, например static-члены в похапе. По умолчанию же все описанные в классе члены индивидуальны для каждого экземпляра.

Но это в прочих языках.
Что, авторы питона изобрели свой собственный велосипед с петанкомм и хористками?

Подскажите pls что конкретно по этому поводу можно почитать, т.к. ни в одном онлайн-руководстве по языку я этого нюанса не видел.

py.user.next
В классе ты определяешь переменные, которые должны быть во всех экземплярах одинаковыми. А вот в экземплярах ты определяешь переменные, которые должны быть уникальными в пределах экземпляра.

Осталось выяснить почему одинаковыми оказываются члены типа “список”.
Если этот самый “член класса” сделать целым числом, то вышеописанной ерунды не происходит и у каждого экземпляра наличествует своё собственное значение члена “.a”

Сейчас проверю еще для “списка”.

Офлайн

#4 Авг. 11, 2019 12:53:32

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

"разделяемый" между различными объекта член класса

W.Thesis
Подскажите pls что конкретно по этому поводу можно почитать
Пространство имен в Python
W.Thesis
Осталось выяснить почему одинаковыми оказываются члены типа “список”.
Концепция изменяемых и не изменяемых данных в Python.
W.Thesis
ни в одном онлайн-руководстве по языку я этого нюанса не видел.
Потому что все онлайн курс предоставляют в той или иной степени поверхностный набор знаний о зяыке программирования.
W.Thesis
Что, авторы питона изобрели свой собственный велосипед с петанкомм и хористками?
А чему вы так удивляетесь? Это же другой язык программирования. Или вы рассчитывали что все яп одинаковые? Посмотрите на С - там классов вообще нет, как и в Go например, как и в Rust. А если вы посмотрите на Haskell, то это настолько другой мир что вообще выворот мозгов.
P.S. и не надо так пассивно-агрессивно относится к чему то новому. Хотя почему то именно в стане PHP'шников такое не редко наблюдается



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#5 Авг. 11, 2019 12:53:47

W.Thesis
Зарегистрирован: 2019-08-11
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

"разделяемый" между различными объекта член класса

W.Thesis
Сейчас проверю еще для “списка”.
то есть для словаря

Словарь - разделяется между экземплярами. Строка - нет. При прочих равных.
Ой, дурдооооом

Офлайн

#6 Авг. 11, 2019 13:05:46

W.Thesis
Зарегистрирован: 2019-08-11
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

"разделяемый" между различными объекта член класса

JOHN_16
А чему вы так удивляетесь? Это же другой язык программирования. Или вы рассчитывали что все яп одинаковые? Посмотрите на С - там классов вообще нет, как и в Go например, как и в Rust. А если вы посмотрите на Haskell, то это настолько другой мир что вообще выворот мозгов.
P.S. и не надо так пассивно-агрессивно относится к чему то новому. Хотя почему то именно в стане PHP'шников такое не редко наблюдается

С - вообще не ООП язык, а го, хруст иже с ними - это маргинальность, от которой ждешь сюрпризов.
Ходовые же, распространённые ООП языки в _этом_ вопросе одинаковы.
Ява, Ц++, пхп, Модула, ОП, Ада - при всей их несхожести, общие принципы ООП у них реализованы ожидаемым образом.

А раздражение лично у меня вызвала не столько эта странная особенность языка, сколько то, что эта критически выжная “мина” не прописана большими красными буквами в каждом первом руководстве. Именно потому, что это - резкой отличие Питона от других прикладных языков.

Офлайн

#7 Авг. 11, 2019 14:44:15

W.Thesis
Зарегистрирован: 2019-08-11
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

"разделяемый" между различными объекта член класса

Так. Я выяснил. ИЧСХ - выяснил у блондинки, которая питона-то и не знает толком, но мозгой шевелить умеет.

Пишу сюда, может кому пригодится. Стыдно, я мог бы и сам догадаться.

Namespace тут роли не играет.
У классов Питона вообще отсуствует специальная секция декларации членов класса!
Это всего лишь часть кода, который будет исполнен один раз в момент объявления класса.
В том случае, если выполняется присвоение вроде prop = 1,2,3 неявным образом создается экземпляр класса “список” со значением 1,2,3 и ссылка на него присваивается члену prop.
Поэтому все объекты этого класса имеют prop указывающий на один и тот же объект-список.

Вот это и причина проблемы.

С целыми числами (и строками) этого не происходит, как я понял, потому, что согласно п 9.1. это “неизменяемый” объект и работа с ними подчинена другим правилам.

Офлайн

#8 Авг. 11, 2019 15:23:27

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

"разделяемый" между различными объекта член класса

W.Thesis
Пишу сюда, может кому пригодится.
Как ваши неправильные домыслы так и домыслы вашей блондинки тут никому не нужны. Информацию надо черпать из документации.

Вы просто пока не умеете создавать поля объектов в питоне. Распространённые ООП языки и питон в вопросе полей объекта абсолютно одинаковы.

Для себя можете считать что такое объявление аналогично объявлению статического члена класса.
Если вам нужно в объекте создать поле, делайте это в функции __init__.

W.Thesis
С целыми числами (и строками) этого не происходит
Правила обращения с изменяемыми и неизменяемыми объектами тут абсолютно одинаковы.

Попробуйте поступить со списком точно также как с целым числом, т.е. вместо:
 self.a.append(1)

 self.a=self.a+[1]
Потом уберите
 a=[]
Почерпнете пищу для ума и повод разобраться что такое присваивание в питоне. :)

А обращаться к статической переменной лучше так: test.a



Отредактировано doza_and (Авг. 11, 2019 15:33:51)

Офлайн

#9 Авг. 11, 2019 16:42:26

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10024
Репутация: +  857  -
Профиль   Отправить e-mail  

"разделяемый" между различными объекта член класса

W.Thesis
Класс - чертёж
В питоне класс - такой же объект, как и всё остальное. Поэтому можно делать и метаклассы - это классы, экземпляры которых являются классами. Так что это вполне нормальное явление, когда обект-класс имеет атрибуты, к которым можно получать доступ напрямую, без создания экземпляра.
Переменная класса всегда может быть переопределена переменной экземпляра.

W.Thesis
Класс - чертёж, объект - изделие.
Это если ООП-пардигму не знаешь и думаешь, что ООП-языки - это и есть ООП. Класс - это множество объектов, сгруппированных по определённому набору признаков. Вот ребятки, которые знают синтаксис записи класса на каком-либо языке (да хоть на всех языках), совершенно не знают, как эти классы придумать сначала и какие из них нужны, а какие - нет. Можно ещё пытаться применять шаблоны ООП, только так всё равно ничего не получается, так как ООП шаблоны никаких классов не создают и при их применении всё уже должно быть придумано.

W.Thesis
Понятия “член класса” и “свойство объекта” в прочих ООП-языках почти эквивалентны
Нет, член класса - это просто какой-то атрибут, тогда как свойство обязательно должно быть доступно снаружи и является частью интерфейса класса наряду с его методами. Свойство - это как метод, только который не надо вызывать.

W.Thesis
Что, авторы питона изобрели свой собственный велосипед с петанкомм и хористками?
Питон погибче таких языков как PHP, Java и уж тем более C++. Поэтому в нём можно делать многие вещи. В C++ попробуй класс куда-нибудь передай в качестве аргумента. В питоне же запросто это делается.

W.Thesis
Если этот самый “член класса” сделать целым числом, то вышеописанной ерунды не происходит и у каждого экземпляра наличествует своё собственное значение члена “.a”
С числом происходит всё то же самое. Просто когда ты его присваиваешь потом в экземпляре, имя отвязывается от старого объекта и привязывается к новому. В списках же имя остаётся привязанным к одному списку и тот просто пополняется в раззные моменты времени.

W.Thesis
С - вообще не ООП язык
При этом на нём можно реализовывать ООП-архитектуры. Не так это удобно, как в языках, в которых для парадигмы ООП есть синтаксический сахар.

W.Thesis
что эта критически выжная “мина” не прописана большими красными буквами в каждом первом руководстве
Странно, что она не описана, но здесь про эту особенность знают все.

W.Thesis
В том случае, если выполняется присвоение вроде prop = 1,2,3 неявным образом создается экземпляр класса “список” со значением 1,2,3 и ссылка на него присваивается члену prop.
Нет никакого члена prop, есть только имя в пространстве имён, которое в любой момент можно отвязать от одного объекта и привязать к другому, и повторять это можно несколько раз.

W.Thesis
С целыми числами (и строками) этого не происходит, как я понял, потому, что согласно п 9.1. это “неизменяемый” объект и работа с ними подчинена другим правилам.
Нет, происходит всё то же самое, просто при замене старый объект выбрасывается, а имя просто привязывается к новому объекту.



Отредактировано py.user.next (Авг. 11, 2019 16:44:50)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version