Prenons l'exemple suivant:
class A:
@property
def x(self): return 5
Donc, bien sûr, appeler la a = A(); a.x
renverra 5
Mais imaginons que vous souhaitiez pouvoir modifier la propriété x.
.__ De cette façon, par exemple:
class A:
@property
def x(self, neg = False): return 5 if not neg else -5
Et appelez-le avec a = A(); a.x(neg=True)
Cela générera une erreur TypeError: 'int' object is not callable
, ce qui est tout à fait normal, car notre x
est évalué en tant que 5
.
Je voudrais donc savoir comment on peut passer plus d’un argument à l’acquéreur de propriété, si cela est possible.
Notez que vous n'avez pas à utiliser property
en tant que décorateur. Vous pouvez très bien l'utiliser à l'ancienne et exposer les méthodes individuelles en plus de la propriété:
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
Cela peut être ou ne pas être une bonne idée en fonction de ce que vous faites avec cela (mais je m'attendrais à voir une excellente justification dans un commentaire si je découvrais ce modèle dans n'importe quel code que je lisais)
Je pense que vous n'avez pas bien compris le but des propriétés.
Si vous créez une propriété x
, vous y accéderez en utilisant obj.x
au lieu de obj.x()
. Après avoir créé la propriété, il est difficile d'appeler directement la fonction sous-jacente.
Si vous voulez passer des arguments, nommez votre méthode get_x
et n'en faites pas une propriété:
def get_x(self, neg=False):
return 5 if not neg else -5
Si vous voulez créer un passeur, procédez comme suit:
class A:
@property
def x(self): return 5
@x.setter
def x(self, value): self._x = value
une propriété ne doit dépendre que de l'objet associé. Si vous souhaitez utiliser certains paramètres externes, vous devez utiliser des méthodes.
Dans votre deuxième exemple, vous utilisez a.x()
comme s'il s'agissait d'une fonction: a.x(neg=True)
. Dans cet esprit, pourquoi ne pas simplement le définir comme une fonction?
Je sais que cette question est ancienne, mais, pour référence, vous pouvez appeler votre propriété avec un argument comme celui-ci:
a = A()
assert a.x == 5
assert A.x.fget(a, True) == -5
Comme d'autres mentionnés par d'autres, cela n'est pas conseillé.
Dans ce cas particulier, vous pouvez définir deux propriétés qui appellent une fonction sous-jacente:
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