Python: как передать более одного аргумента в геттер свойств?
рассмотрим следующий пример:
class A:
@property
def x(self): return 5
так, конечно, называя a = A(); a.x
вернутся 5
но представьте, что вы хотите иметь возможность изменять свойство x.
Вот так, например:
class A:
@property
def x(self, neg = False): return 5 if not neg else -5
и вызовите его с a = A(); a.x(neg=True)
это поднимет TypeError:'int' object is not callable
, это вполне нормально, так как наш x
оценивается как 5
.
Итак, я хотел бы знать, как можно передать более одного аргумента в собственность геттера, если это вообще возможно.
6 ответов
обратите внимание, что вы не есть использовать property
как декоратор. Вы можете с удовольствием использовать его по-старому и выставлять отдельные методы в дополнение к свойству:
class A:
def get_x(self, neg=False):
return -5 if neg else 5
x = property(get_x)
>>> a = A()
>>> a.x
5
>>> a.get_x()
5
>>> a.get_x(True)
-5
Это может быть или не быть хорошей идеей в зависимости от того, что вы с ней делаете (но я ожидал бы увидеть отличное обоснование в комментарии, если бы я столкнулся с этим шаблоном в любом коде, который я просматривал)
Я думаю, вы не до конца поняли назначение свойств.
если вы создаете собственность x
, вы получите доступ к нему с помощью obj.x
вместо obj.x()
.
После создания свойства нелегко вызвать базовую функцию напрямую.
если вы хотите передать аргументы, назовите свой метод get_x
и не делайте это свойством:
def get_x(self, neg=False):
return 5 if not neg else -5
если вы хотите создать сеттер, делай так:
class A:
@property
def x(self): return 5
@x.setter
def x(self, value): self._x = value
свойство должно зависеть только от связанного объекта. Если вы хотите использовать некоторые внешние параметры, вы должны использовать методы.
во втором примере вы используете a.x()
как будто это функция:a.x(neg=True)
. Имея это в виду, почему бы просто не определить его как функцию?
Я знаю, что этот вопрос старый, но для справки вы можете вызвать свое свойство с таким аргументом:
a = A()
assert a.x == 5
assert A.x.fget(a, True) == -5
Как и другие упомянутые другими, это не рекомендуется.
в этом конкретном случае вы можете определить два свойства, которые вызывают базовую функцию:
class A:
@property
def x(self):
return self._x(neg = False)
@property
def x_neg(self):
return self._x(neg = True)
def _x(self, neg):
return 5 if not neg else -5