Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 2, 2018 19:36:24

AlekseyPython
Зарегистрирован: 2018-10-24
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Как избавиться от self в методах классов?

 Класс является пространством имён для своих констант. Ты вообще понимаешь, что в разных классах могут быть константы с одинаковыми именами, но с разными значениями?
Предложения вынести всё из класса в модуль тоже вызывают подозрения, что ты не понимаешь, что делаешь.

Да, я понимаю, что в разных классах могут быть константы с одинаковыми именами и разными значениями (класс выступает в роли контейнера). Но и в разных модулях могут быть константы с одинаковыми именами и разными значениями (тоже контейнер). Чем первое решение лучше второго?
state должно храниться в экземпляре, потому что у меня будет работать одновременно несколько объектов с разными state- ами. Под константой я понимаю общее значение для всех экземляров (например, настройки работы объектов), а не отдельно взятого (если бы я этого не понимал, то предложил бы хранить в модуле все члены объекта, а не только константные).

То ты теряешь модульный функционал.
А это что такое? В каждом модуле у меня будет только по 1 классу (это хорошая практика программирования). Я не хочу заниматься метапрограммированием, меня интересует только работа с классом, импортированным из модуля (который по сути будет представлять интерфейс, поскольку все внутренности из него выброшены в модуль). Поэтому не вижу проблем в предложенном решении при такой парадигме программирования. Программа пишется для конкретной цели без желания создавать переносимые пакеты.

Отредактировано AlekseyPython (Дек. 2, 2018 19:41:36)

Офлайн

#2 Дек. 3, 2018 01:34:23

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

Как избавиться от self в методах классов?

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

AlekseyPython
В каждом модуле у меня будет только по 1 классу (это хорошая практика программирования).
Ты хоть один проект читал?

AlekseyPython
Я не хочу заниматься метапрограммированием
Ты не ориентируешься в понятиях. Складывание классов в модуль - это не метапрограммирование.

Пытаешься из себя изобразить умного, но колешься на мелочах, поэтому выглядишь неприглядно. Это знаешь, как Штирлиц спалился в анекдоте, когда чай пил в кабинете и стал ложечку придерживать. Вроде он офицер немецкий, а чай пьёт, как обычный советский офицер, работающий в поездах.

AlekseyPython
Чем первое решение лучше второго?
Класс инкапсулирует всю свою хрень, относящуюся только к нему. У него есть свои константы, которые касаются только его. У другого класса есть свои константы с теми же именами, относящиеся только к нему. Поэтому, читая код, ты всегда всегда видишь, что константа LEGS_NUMBER принадлежит этому классу или тому.

  
if num == Dog.LEGS_NUMBER:
    return 'dog'
elif num == Cat.LEGS_NUMBER:
    return 'cat'
elif num == Bird.LEGS_NUMBER:
    return 'bird'

А ты предлагаешь
так
  
if num == LEGS_NUMBER:
    return 'dog'
elif num == LEGS_NUMBER:
    return 'cat'
elif num == LEGS_NUMBER:
    return 'bird'

или так
  
if num == mod_dog.LEGS_NUMBER:
    return 'dog'
elif num == kitty.LEGS_NUMBER:
    return 'cat'
elif num == animals.LEGS_NUMBER:
    return 'bird'

Какую читаемость ты повысил? Ты просто понасмешивал всё со всем, потому что на питоне писать не умеешь, не знаешь правил общепринятых.



Отредактировано py.user.next (Дек. 3, 2018 01:35:54)

Офлайн

#3 Дек. 3, 2018 06:52:01

AlekseyPython
Зарегистрирован: 2018-10-24
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Как избавиться от self в методах классов?

Ты не ориентируешься в понятиях. Складывание классов в модуль - это не метапрограммирование.
Вообще- то я отдельно писал, что у меня будет по 1 классу в модуле. Поэтому почему вы решили, что в метапрограммирование я вкладываю именно такой смысл- не понятно (зачем мне дважды писать одно и тоже?). Метапрограммирование я упомянул, потому что единственная проблема, которую я вижу при складировании “потрохов” класса в модуль- “засирание” модуля и как следствие- необходимость это учитывать при динамическом создании классов (нельзя нечаянно “смахнуть” переменные модуля, поскольку они логически связаны с остальным кодом).

Поэтому, читая код, ты всегда всегда видишь, что константа LEGS_NUMBER принадлежит этому классу или тому.
 if num == Dog.LEGS_NUMBER:
    return 'dog'
elif num == Cat.LEGS_NUMBER:
    return 'cat'
elif num == Bird.LEGS_NUMBER:
    return 'bird'

Я придерживаюсь практики программирования, в которой из класса не вытаскивают его потроха, а доверяют ему выполнение необходимых действий (реальное ООП, а не просто использование объектов в качестве контейнера). Поэтому приведеного вами кода у меня никогда не было в проектах и никогда не будет. В реально объектном программировании именно объект реализует весь необходимый функционал и теперь уже, смотря на весь его функционал, можно дать ему точное название, не занимаясь переводом в голове (подобно тому, как люди плохо знающие английский язык, услышав английскую фразу, мысленно переводят ее на русский, думают на русском и чтобы ответить, переводят ее уже на английский).
Егор Бугаенко — Объектно-ориентированное вранье

Отредактировано AlekseyPython (Дек. 3, 2018 06:57:08)

Офлайн

#4 Дек. 3, 2018 09:39:30

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

Как избавиться от self в методах классов?

AlekseyPython
Егор Бугаенко — Объектно-ориентированное вранье
Знаешь, не поленился и полазил у него в репозитории

9 Feb 2015
https://github.com/yegor256/wc/blob/master/wc.c
#include <stdio.h>
#include <unistd.h>
int main() {
char ch;
int count = 0;
while (1) {
if (read(STDIN_FILENO, &ch, 1) <= 0) {
break;
}
if (ch == ' ') {
++count;
}
}
if (count > 0) {
++count;
}
printf("%d\n", count);
return 0;
}

Запустил этот код
[guest@localhost c]$ .ansi wc.c -o wc
[guest@localhost c]$ echo " " | ./wc
2
[guest@localhost c]$


AlekseyPython
Я придерживаюсь практики программирования, в которой из класса не вытаскивают его потроха
Я тебе привёл то, как сделано в Qt. Оно даже не на питоне использует такой подход, хотя в C++ есть конструкция для определения пространства имён для подобных вещей. А в питоне конструкции для определения пространств имён нет, поэтому используются модули и классы. Если выполнишь import this в интерпретаторе, там увидишь одно из правил как раз для пространств имён.



Отредактировано py.user.next (Дек. 3, 2018 13:22:39)

Офлайн

#5 Дек. 3, 2018 09:54:27

AlekseyPython
Зарегистрирован: 2018-10-24
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Как избавиться от self в методах классов?

Я тебе привёл то, как сделано в Qt.

Я не могу уверенно сказать, что знаю весь Qt, но за 1.5 года работы с этим фреймворком я ничего подобного (тому коду что представили вы) там не видел. Вот, например, справка по QThreadPool Class. Не вижу, чтобы в нем была возможность напрямую вытащить (или записать) какие- то внутренности в клиентском коде. Все делается через методы- интерфейсы.

Офлайн

#6 Дек. 3, 2018 10:08:13

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

Как избавиться от self в методах классов?

  
>>> import PyQt5.QtCore
>>> PyQt5.QtCore.Qt.AlignTop
32
>>> PyQt5.QtCore.Qt
<class 'PyQt5.QtCore.Qt'>
>>> PyQt5.QtCore
<module 'PyQt5.QtCore' from '/usr/lib64/python3.6/site-packages/PyQt5/QtCore.so'>
>>> PyQt5
<module 'PyQt5' from '/usr/lib64/python3.6/site-packages/PyQt5/__init__.py'>
>>>

PyQt5 - пакет
PyQt5.QtCore - модуль
PyQt5.QtCore.Qt - класс
PyQt5.QtCore.Qt.AlignTop - константа

Когда класс использует константу, есть смысл замкнуть её в классе, не связывая класс с внешними классами.
  
>>> class Bird:
...     
...     LEGS_NUMBER = 2
...     
...     def fly(self):
...         return 'fly with {} legs'.format(Bird.LEGS_NUMBER)
... 
>>> class Dog:
...     
...     LEGS_NUMBER = 4
...     
...     def run(self):
...         return 'run on {} legs'.format(Dog.LEGS_NUMBER)
... 
>>> def do(legs_number):
...     if legs_number == Dog.LEGS_NUMBER:
...         obj = Dog()
...         val = obj.run()
...     elif legs_number == Bird.LEGS_NUMBER:
...         obj = Bird()
...         val = obj.fly()
...     return (obj, val)
... 
>>> do(2)
(<__main__.Bird object at 0x7fb951251e48>, 'fly with 2 legs')
>>> do(4)
(<__main__.Dog object at 0x7fb951251e80>, 'run on 4 legs')
>>>
Если же мы выводим константы в отдельный класс, то повляется связь с ним и любое изменение какого-то из классов повлечёт за собой исменение того класса с константами. Если же мы держим константы в классе, то изменение этого класса может повлечь изменение только тех классов, которые зависят от него.



Отредактировано py.user.next (Дек. 3, 2018 10:25:48)

Офлайн

#7 Дек. 3, 2018 10:22:49

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

Как избавиться от self в методах классов?

> Или может быть есть какие- то другие пути избавления от self- ада?

Есть. Пользуйся ЯП где не используется подобный подход.

> В каждом модуле у меня будет только по 1 классу (это хорошая практика программирования)

Это ужасная “практика программирования”.



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

Офлайн

#8 Дек. 3, 2018 10:26:10

AlekseyPython
Зарегистрирован: 2018-10-24
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Как избавиться от self в методах классов?

PyQt5 - пакет
PyQt5.QtCore - модуль
PyQt5.QtCore.Qt - класс
PyQt5.QtCore.Qt.AlignTop - константа

PyQt5.QtCore.Qt - неймспейс
PyQt5.QtCore.Qt.Alignment - перечисление неймспейса (не класса!)
PyQt5.QtCore.Qt.AlignTop - одно из значений перечисления

Так что ваш пример мимо кассы: здесь не про возможность вытащить внутренности класса.
Qt Namespace

Отредактировано AlekseyPython (Дек. 3, 2018 10:29:19)

Офлайн

#9 Дек. 3, 2018 10:34:11

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

Как избавиться от self в методах классов?

AlekseyPython
Так что в Qt константы вынесены из классов и лежат в неймспейсе
С которым появляется связь у класса. Тут глобальное пространство имён, с которым связан каждый из классов Qt, использующий константы. Если мы захотим переименовать какие-то константы в пространстве имён, то внутри класса, который эти константы использует, тоже надо будет их переименовывать. Если мы захотим переименовать константы внутри класса, то в пространстве имён их тоже понадобится переименовывать. В этом и есть связь.

Вот, например, константа из пространства имён Qt
Qt::AA_DontShowIconsInMenus
А что же такое вот это “AA” в начале? Читается оно? Нет, надо строить догадки.
А без этого AA имя константы столкнётся с другим таким же именем и вызовет конфликт имён, потому что в этом пространстве имён определены десятки имён для похожих классов.
А когда ты в классе держишь константу, тебе не нужно ей писать AA в начале, потому что сам класс выполняет функцию AA.



Отредактировано py.user.next (Дек. 3, 2018 10:40:44)

Офлайн

#10 Дек. 3, 2018 10:49:46

AlekseyPython
Зарегистрирован: 2018-10-24
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Как избавиться от self в методах классов?

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

Такая проблема возниакает только если у вас неправильный стиль программирования, и вы в клиентском коде пытаетесь вытащить “потроха”, не доверяя функционал самому классу. По сути у вас бизнес- логика размазывается по куче модулей, где вы используете эти константы. ООП предлагает извне использовать только методы- интерфейсы.

Отредактировано AlekseyPython (Дек. 3, 2018 10:50:42)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version