Попытка ответа, основанная на предположении, что вы хотите, чтобы переменные __x#
изменялись только во время __init__
, и никогда больше, но также хотели, чтобы средства доступа следовали по одному и тому же пути кода (возможно, потому что чтение также программно сложно):
В этом случае реализующая функция может принимать дополнительный аргумент по умолчанию.При доступе в форме атрибута он получит аргумент по умолчанию, но если к элементу свойства fget
обращен явно, его можно вызвать с аргументом не по умолчанию.Простой пример, относящийся только к x1
:
class A:
def __init__(self, x):
self.__x = x
# Access the property itself off the class, bypassing execution,
# then call it directly with the non-default argument
type(self).x1.fget(self, True)
@property
def x1(self, doset=False):
if doset:
self.__x1 = self.__x + 1
return self.__x1
В качестве альтернативы, чтобы упростить использование в __init__
, вы можете использовать отдельное имя для базовой функции вместо property
для достижения того же эффекта.:
class A:
def __init__(self, x):
self.__x = x
# Call the implementing function directly with the non-default argument
self._x1(True)
# Implementing function named with single underscore prefix to indicate it's
# for internal/protected use only
def _x1(self, doset=False):
if doset:
self.__x1 = self.__x + 1
return self.__x1
# Define property x1 based on x1 for outside use
x1 = property(_x1)
Конечно, если у вас нет сложного пути получения, тогда реальное решение - полностью отделить _x1
от x1
, где _x1
- это чистая вспомогательная функция для установки__init__
, а x1
- чистый получатель:
class A:
def __init__(self, x):
self.__x = x
# Call the init helper
self._init_x1()
# Implementing function named with single underscore prefix to indicate it's
# for internal/protected use only
def _init_x1(self):
self.__x1 = self.__x + 1
@property:
def x1(self):
return self.__x1
Для ясности, только последний из них - "Pythonic" в любом значимом смысле.Второй вариант имеет несколько ограниченных вариантов использования (когда у вас есть функция, которая требует существования, и она легко настраивается, но имеет разумный набор значений по умолчанию, которые может использовать property
), но в этом случае обычно это функция, которая имеетобщественная полезность так же, как property
.Вариант № 1 является наименее Pythonic, так как его неудобно использовать (необходимо повысить уровень до класса, извлечь член fget
и явно передать self
), и ясно дает понять, что за пределами ожидаемого варианта использования нет__init__
(потому что это такая боль, которую никто не побеспокоит).