Je suis généralement confus à propos de la différence entre "propriété" et un "attribut", et ne peut pas trouver une grande ressource d'une manière concise détail les différences.
Réponses
Trop de publicités?Propriétés particulières de l'attribut. En gros, quand Python rencontres le code suivant:
spam = SomeOjbect()
print(spam.eggs)
il regarde eggs
en spam
, et une fois qu'il l'a il examine ensuite eggs
pour voir si il a un __get__
, __set__
ou __delete__
méthode, si elle le fait, c'est une propriété. Si c' est une propriété, au lieu de simplement retourner le eggs
objet (comme il le ferait pour n'importe quel autre attribut) il va appeler l' __get__
méthode (puisque nous faisions de recherche) et de retour quelle que soit la méthode renvoie la.
Plus d'informations sur Python du modèle de données et des descripteurs.
Avec une propriété que vous avez le contrôle complet sur son getter, setter et deleter méthodes, chose que vous n'avez pas (si vous n'utilisez pas mises en garde) avec un attribut.
class A(object):
_x = 0
'''A._x is an attribute'''
@property
def x(self):
'''
A.x is a property
This is the getter method
'''
return self._x
@x.setter
def x(self, value):
"""
This is the setter method
where I can check it's not assigned a value < 0
"""
if value < 0:
raise ValueError("Must be >= 0")
self._x = value
>>> a = A()
>>> a._x = -1
>>> a.x = -1
Traceback (most recent call last):
File "ex.py", line 15, in <module>
a.x = -1
File "ex.py", line 9, in x
raise ValueError("Must be >= 0")
ValueError: Must be >= 0
En général, parlent une propriété et d'un attribut sont la même chose. Cependant, il existe une propriété décorateur en Python qui fournit des getter/setter accès à un attribut (ou d'autres données).
class MyObject(object):
# This is a normal attribute
foo = 1
@property
def bar(self):
return self.foo
@bar.setter
def bar(self, value):
self.foo = value
obj = MyObject()
assert obj.foo == 1
assert obj.bar == obj.foo
obj.bar = 2
assert obj.foo == 2
assert obj.bar == obj.foo
La propriété vous permet d'obtenir et de définir les valeurs comme vous le feriez des attributs, mais en dessous il y a une méthode appelée le traduire dans un getter et setter pour vous. C'est vraiment juste une commodité pour les couper vers le bas sur le standard de l'appel de getters et setters.
Disons par exemple, vous avez eu une classe qui a tenu certaines de coordonnées x et y pour quelque chose dont vous avez besoin. Pour définir entre eux vous pourriez vouloir faire quelque chose comme:
myObj.x = 5
myObj.y = 10
C'est beaucoup plus facile de regarder et de penser à propos de l'écriture:
myObj.setX(5)
myObj.setY(10)
Le problème c'est que si un jour votre classe, les changements que vous avez besoin pour compenser votre x et y par une certaine valeur? Maintenant vous devez aller et changer votre définition de la classe et tout le code qui l'appelle, qui pourrait être vraiment fastidieuse et source d'erreurs. La propriété vous permet d'utiliser l'ancienne syntaxe, tout en vous donnant la flexibilité de changement de ce dernier.
En Python, vous pouvez définir des getters, setters, et supprimer des méthodes avec la propriété de la fonction. Si vous voulez juste la lecture de la propriété, il y a aussi @property décorateur vous pouvez ajouter au-dessus de votre méthode.