Je suis intéressé par la façon de l'utiliser @property
en Python. J'ai lu la documentation python et l'exemple là-bas, à mon avis, n'est qu'un code jouet:
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
Je ne sais pas quel (s) avantage (s) je peux tirer d'emballer le _x
rempli avec le décorateur. Pourquoi ne pas simplement mettre en œuvre comme:
class C(object):
def __init__(self):
self.x = None
Je pense que la fonction de propriété peut être utile dans certaines situations. Mais quand? Quelqu'un pourrait-il me donner des exemples du monde réel?
Merci.
Réponses:
D'autres exemples seraient la validation / filtrage des attributs de l'ensemble (les forçant à être dans des limites ou acceptables) et l'évaluation paresseuse de termes complexes ou changeant rapidement.
Calcul complexe caché derrière un attribut:
Validation:
la source
Un cas d'utilisation simple sera de définir un attribut d'instance en lecture seule, comme vous le savez, le fait de diriger un nom de variable avec un trait
_x
de soulignement en python signifie généralement qu'il est privé (usage interne), mais parfois nous voulons être en mesure de lire l'attribut d'instance et non d'écrire afin que nous puissions l'utiliserproperty
pour cela:la source
c._x
, si l'utilisateur le souhaite. Python n'a en fait pas de vrais attributs privés.Jetez un œil à cet article pour une utilisation très pratique. En bref, il explique comment en Python, vous pouvez généralement abandonner la méthode getter / setter explicite, car si vous en avez besoin à un moment donné, vous pouvez l'utiliser
property
pour une implémentation transparente.la source
Une chose pour laquelle je l'ai utilisé est la mise en cache des valeurs lentes à rechercher, mais inchangées, stockées dans une base de données. Cela se généralise à toute situation où vos attributs nécessitent un calcul ou une autre opération longue (par exemple, vérification de la base de données, communication réseau) que vous ne voulez faire qu'à la demande.
C'était dans une application Web où une vue de page donnée pouvait ne nécessiter qu'un seul attribut particulier de ce type, mais les objets sous-jacents eux-mêmes pouvaient avoir plusieurs de ces attributs - les initialiser tous lors de la construction serait un gaspillage, et les propriétés me permettent d'être flexible dans lequel les attributs sont paresseux et qui ne le sont pas.
la source
@cached_property
pour ça?En lisant les réponses et les commentaires, le thème principal semble être les réponses semblent manquer d'un exemple simple mais utile. J'en ai inclus un très simple ici qui démontre l'utilisation simple du
@property
décorateur. C'est une classe qui permet à un utilisateur de spécifier et d'obtenir une mesure de distance en utilisant une variété d'unités différentes, c'estin_feet
-à- dire ouin_metres
.Usage:
la source
La propriété est juste une abstraction autour d'un champ qui vous donne plus de contrôle sur la manière dont un champ spécifique peut être manipulé et pour effectuer des calculs middleware. Peu des usages qui me viennent à l'esprit sont la validation et l'initialisation préalable et la restriction d'accès
la source
Oui, pour l'exemple d'origine publié, la propriété fonctionnera exactement de la même manière qu'une simple variable d'instance «x».
C'est la meilleure chose à propos des propriétés python. De l'extérieur, elles fonctionnent exactement comme des variables d'instance! Ce qui vous permet d'utiliser des variables d'instance en dehors de la classe.
Cela signifie que votre premier exemple pourrait en fait utiliser une variable d'instance. Si les choses ont changé et que vous décidez de modifier votre implémentation et qu'une propriété est utile, l'interface avec la propriété serait toujours la même à partir du code en dehors de la classe. Un changement de variable d'instance à propriété n'a aucun impact sur le code en dehors de la classe.
De nombreux autres langages et cours de programmation indiqueront qu'un programmeur ne doit jamais exposer de variables d'instance, et utiliser à la place des `` getters '' et des `` setters '' pour toute valeur accessible depuis l'extérieur de la classe, même le cas simple cité dans la question.
Code en dehors de la classe avec de nombreux langages (par exemple Java) utilisent
Et lors de l'implémentation de la classe, il y a de nombreux 'getters' et 'setters' qui font exactement comme votre premier exemple: répliquer simplement une variable d'instance. Ces getters et setters sont nécessaires car si l'implémentation de la classe change, tout le code en dehors de la classe devra changer. Mais les propriétés python permettent au code en dehors de la classe d'être le même que celui des variables d'instance. Ainsi, le code en dehors de la classe n'a pas besoin d'être modifié si vous ajoutez une propriété ou si vous avez une variable d'instance simple. Donc, contrairement à la plupart des langages orientés objet, pour votre exemple simple, vous pouvez utiliser la variable d'instance au lieu des `` getters '' et des `` setters '' qui ne sont vraiment pas nécessaires, sachant que si vous passez à une propriété à l'avenir, le code utilisant votre classe n'a pas besoin de changer.
Cela signifie que vous n'avez besoin de créer des propriétés que s'il y a un comportement complexe, et pour le cas simple très courant où, comme décrit dans la question, une simple variable d'instance est tout ce qui est nécessaire, vous pouvez simplement utiliser la variable d'instance.
la source
une autre fonctionnalité intéressante des propriétés sur l'utilisation des setters et des getters est qu'ils vous permettent de continuer à utiliser OP = opérateurs (par exemple + =, - =, * = etc) sur vos attributs tout en conservant toute validation, contrôle d'accès, mise en cache, etc. les setters et les getters fourniraient.
par exemple, si vous avez écrit la classe
Person
avec un settersetage(newage)
et un gettergetage()
, alors pour incrémenter l'âge, vous devrez écrire:mais si vous faites
age
une propriété, vous pourriez écrire le plus propre:la source
La réponse courte à votre question est que dans votre exemple, il n'y a aucun avantage. Vous devriez probablement utiliser le formulaire qui n'implique pas de propriétés.
La raison pour laquelle les propriétés existent, c'est que si votre code change dans le futur, et que vous devez soudainement faire plus avec vos données: mettre en cache les valeurs, protéger l'accès, interroger une ressource externe ... peu importe, vous pouvez facilement modifier votre classe pour ajouter des getters et setters pour les données sans changer l'interface, vous n'avez donc pas à trouver partout dans votre code où ces données sont accessibles et à changer cela aussi.
la source
Ce que beaucoup ne remarquent pas au début, c'est que vous pouvez créer vos propres sous-classes de propriétés. J'ai trouvé cela très utile pour exposer des attributs d'objets en lecture seule ou des attributs que vous pouvez lire et écrire mais pas supprimer. C'est également un excellent moyen d'encapsuler des fonctionnalités telles que le suivi des modifications des champs d'objets.
la source
attr = reader('_attr')
ligne ou une forme de pré-vérification commeattr = if self.__isValid(value): reader('_attr')
. Suggestions?attr = reader('_attr')
pourattr = accessor('_attr')
. Merci