Найти - Пользователи
Полная версия: Еще про стиль написания программ.
Начало » Python для экспертов » Еще про стиль написания программ.
1 2 3
ice
Доброго времени суток!

Есть у меня просто класс

class test:
..............
field = 1
..............
field - это характеристика, которая нужна извне.
как лучше:

t = test()
.....
blabla = t.field
или же

class test:
..............
_field = 1
..............
def field(self):
return self._field
..............
t = test()
.....
blabla = t.field()
вообще есть принципиальная разница в подходах?
во втором случае, на сколько понимаю, извне нельзя переменную изменить, а в первом можно … тоесть во втором случае мне придется писать чот-то типа
set_field()

как правильнее писать подобное? И если у меня таких полей штук 20 …
Ferroman
Тут разница именно в принципе.
В первом случае - это аналог public поля, а во втором - private. Инкапсуляция в питоне не реализована на уровне языка, а реализовывается
так, как это сделано во втором примере.
То есть на примере 2 объявляют поле ‘__название’ если это поле будет использоваться только методами этого класса, а доступ напрямую из вне не предусматривается. В первом случае - предусматривается чтение/запись не только внутри класса.
Кроме того есть ещё property().

А как правильно писать - зависит от цели.
ice
То есть, если мне нужно извне менять это поле, то можно его оставить просто как field и не писать обертки и это нормально с точки зрения питона?

вопрос возник когда знакомый сказал, что такой доступ к полям это не хорошо и надо обязательно писать геттеры и сеттеры.
Он, правда на яве программирует. может там такое обязательно…
evgenyl
Твой друг прав, это проблема идеалогии и уровня абстракций
Сейчас это просто поле, а завтра его нужно будет проверять на валидность, сбрасывать кэш и ещё бог знает что
Поэтому пишут сеттер и геттер чтобы потом проще менять логику.

Но в обычном приложении это не столь важно
Ferroman
То есть, если мне нужно извне менять это поле, то можно его оставить просто как field и не писать обертки и это нормально с точки зрения питона?
Да.
вопрос возник когда знакомый сказал, что такой доступ к полям это не хорошо и надо обязательно писать геттеры и сеттеры.
Он, правда на яве программирует. может там такое обязательно…
Да, в Java это уже практически правило, хотя есть возможность писать и public поля, насколько я знаю. Но там хорошим тоном есть инкапсуляция таких данных. Я против избыточности в коде, и использую такой доступ к полям, только если они составные или требуют валидации/форматирования.
Это удобно делать через property, особенно если поле существует давно, и просто нужно дописать новый функционал, а на него много чего завязано уже.
Хороший пример использования есть на сайте django (http://www.djangoproject.com/documentation/models/properties) и здесь есть простой пример.
Ferroman
lorien
Насколько я знаю подчёркивание просто определяет метод/поле как внутреннее для программиста, и никак не ограничивается при использовании. Просто программист встретив такое оформление будет знать, что код используется только внутри класса, и использование его в другом месте нежелательно.
Александр Кошелев
Ferroman
В первом случае - это аналог public поля, а во втором - private.
хм… private было бы, если два подчеркивания перед именем…
Ferroman
Daevaorn
Да, абсолютно правильно, исправил.

Дополнение:
Одиночное подчёркивание в начале имени атрибута говорит о том, что метод не предназначен для использования вне методов класса (или вне функций и классов модуля), однако, атрибут все-таки доступен по этому имени. Два подчёркивания в начале имени дают несколько большую защиту: атрибут перестает быть доступен по этому имени.
PooH
Ferroman
Это удобно делать через property, особенно если поле существует давно, и просто нужно дописать новый функционал, а на него много чего завязано уже.
У property есть один неприятный момент при наследовании:
class A(object):
def _get_name(self):
return 'A'
name = property(_get_name)

class B(A):
def _get_name(self):
return 'B'

In [10]: b.name
Out[10]: 'A'
:(
vigorouz
PooH
У property есть один неприятный момент при наследовании:
In [10]: b.name
Out[10]: 'A'
:(
перекрытие самого свойства решает проблему
class B(A):
def _get_name(self):
return 'B'
name = property(_get_name)

>>> b = B()
>>> b.name
'B'
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