Найти - Пользователи
Полная версия: Подскажите, почему программисты на питон не используют такой стиль кода?
Начало » Python для экспертов » Подскажите, почему программисты на питон не используют такой стиль кода?
1 2 3 4 5
FishHook
Nab
У меня же имена на русском
Имена переменных? На русском?
Nab
но только в том случае, если влазит в строку
Ну перенесите на другую строку, если не влазит. Из-за того, что не влазит в строку надо говнокодить,
вводить в код ветвления там где они не нужны, вместо того чтобы просто вернуть результат логической операции?
Nab
Паттерны питоновские я смотрел
Покажите где смотрели, тоже хочется.
Nab
Ну и на питоне можно метода писать… В чём суть претензий я так и не понял.
В том что они нахер не нужны! Ни методы, ни проперти.
Что тут можно не понять то?
Nab
Для интерфейса класса - так понятно
Скажите, чем вам вот такой интерфейс
class A:
   def__init__(self):
      self.foo = 1
хуже чем такой
class A:
   def__init__(self):
      self.__foo = 1
  @property
  def foo(self):
      return self.__foo
PooH
4kpt_IV
Укажите в книге этот принцип, если можно. Я про него не слышал.
Это один из принципов SOLID, они очень общи, и ТС как-то невероятно упрощенно его понимает. Я читал у Роберта Мартина в “Быстрая разработка программного обеспечения” ISBN 5-8459-0558-3, вторая часть.
Nab
FishHook
Ну перенесите на другую строку, если не влазит.
Да, ваш пример лучше. Согласен.

FishHook
Покажите где смотрели, тоже хочется.
У Саммерфилда. Думаю, вы тут вкурсе.

FishHook
Скажите, чем вам вот такой интерфейс, хуже чем такой
Ну ладно. Теперь понимаю, что вы просто не вкурсе поэтому объясню: инкапсуляция данных нарушается - атрибут, у вас, изначально открыт.

Вообще, в питоне принято property писать, даже если переменная с одним подчёркиванием.

ПС: неважно, что “псевдо”.

Вообщем, по ответам отписавшихся, я суть уже уловил.
Все кто ответил, имеют хорошую репутацию, и видно, что “не первый год замужем”.
Спасибо, за уделённое время.
doza_and
Nab
инкапсуляция данных нарушается - атрибут, у вас, изначально открыт.
Вы много внимания уделяете закрытости, а в питоне вообще нет закрытых атрибутов. Даже если вы понатыкаете подчеркиваний, нет гарантий отсутствия доступа к этому полю.
Nab
Вообще, в питоне принято property писать, даже если переменная с одним подчёркиванием.
Мне кажется вас ввели в заблуждение примеры использования property. Из того что я встречал, они используются когда надо выполнить дополнительные действия при доступе к атрибуту.
Переменная с подчеркиванием появляется в примере когда надо освободить имя для свойства. На практике при появлении свойств обычно вообще нет одноименной переменной с подчеркиванием.
py.user.next
doza_and
Переменная с подчеркиванием появляется в примере когда надо освободить имя для свойства.
Атрибуты с подчёркиванием в начале не включаются в help, будь то поля или методы.
>>> class A:
...   a = 1
...   _b = 2
...   
...   def c(self):
...     pass
...   
...   def _d(self):
...     pass
... 
>>> help(A)

Help on class A in module __main__:
class A(builtins.object)
 |  Methods defined here:
 |  
 |  c(self)
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  a = 1

И свойства используются тогда, когда ты напрямую получаешь доступ к атрибуту.
>>> class A:
...     
...     _a = None
...     
...     def __init__(self, a):
...         self._a = a
...     
...     @property
...     def a(self):
...         """Свойство ашности"""
...         return self._a
... 
>>> a = A(1)
>>> a.a
1
>>> a.a = 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>> 
>>> help(a)

Help on A in module __main__ object:
class A(builtins.object)
 |  Methods defined here:
 |  
 |  __init__(self, a)
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)
 |  
 |  a
 |      Свойство ашности

FishHook
Скажите, чем вам вот такой интерфейс
class A:
   def__init__(self):
      self.foo = 1
Это не интерфейс, интерфейс - это то, что ты можешь использовать снаружи. А в данном случае self.foo создана для использования изнутри. Если ты начнёшь её использовать снаружи, то наружние пользователи свяжут её. Что это значит: когда ты захочешь прорефакторить (или дополнить) этот класс и окажется, что её нужно переименовать или вообще удалить, ты не сможешь этого сделать, потому что наружние пользователи будут её искать. Когда же у тебя свойство, оно остаётся в любом случае, а внутреннее устройство класса может становиться любым.

Nab
У меня же имена на русском, ещё более ёмкие по смыслу и более длинные.
Это безграмотная хрень, когда ты не можешь делать короткие и ясные имена. Никто не будет читать километровые имена, на это просто нет времени.

Nab
В сях, джаве или шарпе, был бы метод.
Мимо этого тоже невозможно пройти. В C нет методов, ты путаешь C и C++. Это разные языки. В частности, интерпретатор питона написан на C89, поэтому классов в его исходниках не найдёшь.
FishHook
py.user.next
Что это значит: когда ты захочешь прорефакторить (или дополнить) этот класс и окажется, что её нужно переименовать или вообще удалить, ты не сможешь этого сделать, потому что наружние пользователи будут её искать. Когда же у тебя свойство, оно остаётся в любом случае, а внутреннее устройство класса может становиться любым.
Наружние пользователи точно так же будут искать свойство, которое я решу порефакторить и удалить или переименовать.
Когда в процессе развития проекта я решу усложнить логику, я всегда могу из этого
class A:
    def __init__(self):
        self.a = 1
сделать это
class A:
    def __init__(self):
        self._a = 1
    @property
     def a(self):
          if self._a > 1:
              self.warning("A > 1")
          return self._a
и наружние пользователи ни о чем не догадаются. Делать бестолковые затычки заранее, называя это хорошим стилем,
глупо и ненужно.


FishHook
Nab
атрибут, у вас, изначально открыт
И что же в этом плохого?
py.user.next
FishHook
Наружние пользователи точно так же будут искать свойство, которое я решу порефакторить и удалить или переименовать.
Свойство никакого отношения к внутренностям не имеет, оно делается для внешних пользователей, которые просто читают внешнее описание класса.
Вот ты знаешь, как устроена функция int() в питоне? Нет ведь, потому что тебе это не надо, ты - пользователь этой функции. Поэтому её можно внутри переделывать спокойно, а ты даже об этом не узнаешь никогда. Её будут сто раз переделывать, а ты ни разу об этом не узнаешь.
То же самое и со свойствами, свойство ты не можешь просто взять и поменять, потому что оно является частью интерфейса. А вот эти внутренние переменные ты можешь менять, как хочешь, потому что нормальные люди не будут на них базировать свой код. А кто пробазировал, ну, они - сами себе злобные буратины, сломаются у них программы тогда. Ты им свойств этих не предоставлял, а они там сами что-то решили.

FishHook
Когда в процессе развития проекта я решу усложнить логику, я всегда могу из этого
class A:
    def __init__(self):
        self.a = 1
Не, а ты из вот этого, сделай вот это
class A:
    def __init__(self):
        self.some_a = 1
Чтобы класс так же работал, а внутри всё хранилось по-другому, с более подробными именами. Ты хоп такой и думаешь “ой, а у меня же этот атрибут наружу торчит, я не могу его менять” и “пускай по-старому называется, а я как-нибудь привыкну, свернусь калачиком”.
FishHook
py.user.next
Да блин!!!
Ну сделал я так
class A:
    def __init__(self):
         self.__some = 1
    @property
     def some(self):
         return self.__some
Дал пользователю внешний интерфейс и инкапсулировал атрибут. Все прекрасно! Могу изменять self.__some как угодно, при этом свойство some я никуда деть не могу, потому что это интерфейс.
Для пользователя свойство some и обычный атрибут объекта some - без разницы и я могу его превратить в свойство когда угодно, не изменяя при этом интерфейс.
py.user.next
В том-то и дело, что внутренние поля не входят в интерфейс, поэтому ты можешь их менять, как хочешь и когда угодно. А когда они у тебя входят в интерфейс, то ты их не можешь менять никогда.

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

Вот у тебя был код
>>> class A:
...     def __init__(self):
...         self.a = 1
...         self.b = 2
... 
>>> def f():
...     a = A()
...     return a.a, a.b
... 
>>> f()
(1, 2)
>>>

Вот ты заменил имя переменной в классе
>>> class A:
...     def __init__(self):
...         self.some_a = 1
...         self.b = 2
... 
>>> def f():
...     a = A()
...     return a.a, a.b
... 
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in f
AttributeError: 'A' object has no attribute 'a'
>>>

Вот ты исправил ошибку, чтобы функция увидела старое поле
>>> class A:
...     def __init__(self):
...         self.some_a = 1
...         self.b = 2
...     
...     @property
...     def a(self):
...         return self.some_a
... 
>>> def f():
...     a = A()
...     return a.a, a.b
... 
>>> f()
(1, 2)
>>>
И что мы видим? Переменная a - в виде свойства, а переменная b - в виде поля. И тут возникает вопрос: а что переменная b может быть изменена без лишних телодвижений или она используется где-то и надо будет делать из неё свойство?
По идее, ты должен был в функции f() изменить переменную a.a на переменную a.some_a, чтобы красоту класса сохранить. Но только функций таких может быть сто.

Ещё есть запись свойств, но это “уже совсем другая история, страна…”. (Просто не стал усложнять тут повествование.)
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