Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 13, 2008 14:40:58

ice
От:
Зарегистрирован: 2008-01-12
Сообщения: 156
Репутация: +  0  -
Профиль   Отправить e-mail  

Еще про стиль написания программ.

Доброго времени суток!

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

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 …



Отредактировано (Окт. 13, 2008 14:43:50)

Офлайн

#2 Окт. 13, 2008 14:52:18

Ferroman
От:
Зарегистрирован: 2006-11-16
Сообщения: 2759
Репутация: +  1  -
Профиль   Отправить e-mail  

Еще про стиль написания программ.

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

А как правильно писать - зависит от цели.

Отредактировано (Окт. 14, 2008 00:07:40)

Офлайн

#3 Окт. 13, 2008 15:30:32

ice
От:
Зарегистрирован: 2008-01-12
Сообщения: 156
Репутация: +  0  -
Профиль   Отправить e-mail  

Еще про стиль написания программ.

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

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



Отредактировано (Окт. 13, 2008 15:31:12)

Офлайн

#4 Окт. 13, 2008 16:37:44

evgenyl
От:
Зарегистрирован: 2008-07-22
Сообщения: 148
Репутация: +  0  -
Профиль   Отправить e-mail  

Еще про стиль написания программ.

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

Но в обычном приложении это не столь важно



Офлайн

#5 Окт. 13, 2008 16:51:05

Ferroman
От:
Зарегистрирован: 2006-11-16
Сообщения: 2759
Репутация: +  1  -
Профиль   Отправить e-mail  

Еще про стиль написания программ.

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

Отредактировано (Окт. 13, 2008 16:53:17)

Офлайн

#6 Окт. 13, 2008 16:56:00

Ferroman
От:
Зарегистрирован: 2006-11-16
Сообщения: 2759
Репутация: +  1  -
Профиль   Отправить e-mail  

Еще про стиль написания программ.

lorien
Насколько я знаю подчёркивание просто определяет метод/поле как внутреннее для программиста, и никак не ограничивается при использовании. Просто программист встретив такое оформление будет знать, что код используется только внутри класса, и использование его в другом месте нежелательно.

Офлайн

#7 Окт. 13, 2008 19:57:18

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

Еще про стиль написания программ.

Ferroman
В первом случае - это аналог public поля, а во втором - private.
хм… private было бы, если два подчеркивания перед именем…



Офлайн

#8 Окт. 14, 2008 00:08:32

Ferroman
От:
Зарегистрирован: 2006-11-16
Сообщения: 2759
Репутация: +  1  -
Профиль   Отправить e-mail  

Еще про стиль написания программ.

Daevaorn
Да, абсолютно правильно, исправил.

Дополнение:

Одиночное подчёркивание в начале имени атрибута говорит о том, что метод не предназначен для использования вне методов класса (или вне функций и классов модуля), однако, атрибут все-таки доступен по этому имени. Два подчёркивания в начале имени дают несколько большую защиту: атрибут перестает быть доступен по этому имени.

Отредактировано (Окт. 14, 2008 03:00:20)

Офлайн

#9 Окт. 14, 2008 05:24:07

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Еще про стиль написания программ.

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'
:(



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#10 Окт. 14, 2008 10:39:55

vigorouz
От:
Зарегистрирован: 2008-05-19
Сообщения: 20
Репутация: +  0  -
Профиль   Отправить e-mail  

Еще про стиль написания программ.

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'



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version