Voici un autre exemple :
##
## Exemple de propriétés en Python
##
classe GetterSetterExample( object ):
## Définir la valeur par défaut pour x (nous y référençons en utilisant self.x, définissons une valeur en utilisant self.x = valeur)
__x = None
##
## À l'initialisation de la classe - faire quelque chose... si nous le souhaitons..
##
def __init__( self ):
## Définir une valeur pour __x à travers le getter / setter... Puisque __x est défini ci-dessus, cela n'a pas besoin d'être défini...
self.x = 1234
return None
##
## Définir x comme une propriété, c'est-à-dire un getter - Tous les getters devraient avoir un argument de valeur par défaut, donc je l'ai ajouté - il ne sera pas passé lors du paramétrage d'une valeur, vous devez donc définir la valeur par défaut ici pour qu'elle soit utilisée..
##
@property
def x( self, _default = None ):
## J'ai ajouté un argument de valeur par défaut facultatif car tous les getters devraient avoir ceci - définissez-le sur la valeur par défaut que vous voulez retourner...
_value = ( self.__x, _default )[ self.__x == None ]
## Débogage - pour que vous puissiez voir l'ordre des appels...
print('[ Test Class ] Get x = ' + str( _value ) )
## Retourner la valeur - nous sommes un getter après tout...
return _value
##
## Définir la fonction setter pour x...
##
@x.setter
def x( self, _value = None ):
## Débogage - pour que vous puissiez voir l'ordre des appels...
print('[ Test Class ] Set x = ' + str( _value ) )
## Cela montre que la fonction setter fonctionne.... Si la valeur est supérieure à 0, définissez-la sur une valeur négative... sinon gardez-la telle quelle (0 est la seule valeur non-négative, elle ne peut être ni négative ni positive de toute façon)
if ( _value > 0 ):
self.__x = -_value
else:
self.__x = _value
##
## Définir la fonction de suppression pour x...
##
@x.deleter
def x( self ):
## Libérer l'affectation / les données pour x
if ( self.__x != None ):
del self.__x
##
## Fonction de chaîne / sortie pour la classe - cela montrera la valeur de propriété pour chaque propriété que nous ajoutons...
##
def __str__( self ):
## Afficher les données de la propriété x...
print('[ x ] ' + str( self.x ) )
## Retourner une nouvelle ligne - techniquement nous devrions retourner une chaîne afin qu'elle puisse être imprimée où nous le voulons, au lieu d'être imprimée tôt si _data = str( C( ) ) est utilisé....
return '\n'
##
##
##
_test = GetterSetterExample()
print(_test)
## Pour une raison quelconque, la fonction de suppression n'est pas appelée...
del _test.x
Essentiellement, c'est la même chose que l'exemple C( object ) sauf que j'utilise x à la place... Je n'initialise pas non plus dans __init - ... bon... en fait, si, mais ça peut être enlevé parce que __x est défini comme partie de la classe...
La sortie est :
[ Test Class ] Set x = 1234
[ Test Class ] Get x = -1234
[ x ] -1234
et si je commente self.x = 1234 dans init alors la sortie est :
[ Test Class ] Get x = None
[ x ] None
et si je définis _default = None en _default = 0 dans la fonction getter (car tous les getters devraient avoir une valeur par défaut mais elle n'est pas passée par les valeurs de propriété d'après ce que j'ai vu, donc vous pouvez la définir ici, et en fait ce n'est pas mal car vous pouvez définir la valeur par défaut une fois et l'utiliser partout) c'est-à-dire : def x( self, _default = 0) :
[ Test Class ] Get x = 0
[ x ] 0
Remarque : La logique du getter est là juste pour que la valeur soit manipulée par lui pour s'assurer qu'elle est manipulée par lui - de même pour les instructions d'impression...
Remarque : Je suis habitué à Lua et à être capable de créer dynamiquement plus de 10 assistants quand j'appelle une seule fonction et j'ai fait quelque chose de similaire pour Python sans utiliser de propriétés et cela fonctionne dans une certaine mesure, mais, même si les fonctions sont créées avant d'être utilisées, il y a encore parfois des problèmes avec leur appel avant d'être créées ce qui est étrange car ce n'est pas codé de cette façon... Je préfère la flexibilité des métatables Lua et le fait que je peux utiliser de véritables setters / getters au lieu d'accéder directement à une variable... J'aime cependant la rapidité avec laquelle certaines choses peuvent être construites avec Python - par exemple les programmes d'interface graphique. bien que celui que je conçois puisse ne pas être possible sans beaucoup de bibliothèques supplémentaires - si je le code en AutoHotkey je peux accéder directement aux appels dll dont j'ai besoin, et la même chose peut être faite en Java, C#, C++, et plus - peut-être que je n'ai pas encore trouvé la bonne chose mais pour ce projet je pourrais passer de Python...
Remarque : La sortie de code sur ce forum est cassée - j'ai dû ajouter des espaces au début du code pour le faire fonctionner - lorsque vous copiez / collez assurez-vous de convertir tous les espaces en tabulations.... J'utilise des tabulations pour Python car dans un fichier de 10 000 lignes la taille du fichier peut être de 512 Ko à 1 Mo avec des espaces et de 100 à 200 Ko avec des tabulations ce qui équivaut à une différence massive de taille de fichier et à une réduction du temps de traitement...
Les tabulations peuvent également être ajustées par utilisateur - donc si vous préférez une largeur de 2 espaces, 4, 8 ou autre, vous pouvez le faire ce qui est réfléchi pour les développeurs avec des déficiences visuelles.
Remarque : Toutes les fonctions définies dans la classe ne sont pas indentées correctement à cause d'un bug dans le logiciel du forum - assurez-vous de l'indenter si vous copiez / collez
28 votes
Voir aussi: Comment fonctionnent les propriétés Python?
6 votes
property
est en fait une classe (pas une fonction), bien qu'elle appelle probablement la méthode__init__()
lorsque vous créez un objet, bien sûr. Utiliserhelp(property)
depuis le terminal est instructif.help
est également une classe pour une raison quelconque.4 votes
Je pense que ce lien offre un bon exemple : [propriété] (journaldev.com/14893/python-property-decorator)
9 votes
@Shule fil de discussion de 2 ans, mais toujours : Tout est une classe. Même les classes.
5 votes
Cela était aussi déroutant pour moi. J'ai finalement trouvé un article qui a pu simplifier les choses pour moi. J'espère que cela aidera quelqu'un d'autre. programiz.com/python-programming/property Je ne suis en aucun cas affilié au site.
0 votes
De nombreuses réponses dans cette discussion expliquent comment fonctionne
@property
, mais ne traitent pas pourquoi vous l'utiliseriez. La question "pourquoi utiliser@property
en Python" est l'équivalent de "pourquoi utiliser des accesseurs (getters/setters/deleters) en Java", car@property
est l'équivalent pythonique du même concept. Ces discussions complémentaires ont quelques discussions utiles stackoverflow.com/questions/1568091/… stackoverflow.com/questions/6618002/…0 votes
Sur l'utilité du décorateur de propriété : betterprogramming.pub/…
0 votes
ici un sujet connexe sur comment implémenter dynamiquement le protocole de descripteurs getter/setter
0 votes
J'ai une question liée à cette question. Dans l'exemple fourni, il y a un attribut protégé
self._x
, qui est protégé. Mais en utilisant la propriété définie ci-dessus, on peut définir et lire l'attribut en tapant simplementc = C(), c.x = 99
permettant ainsi à tous les programmeurs d'utiliser cet attribut comme s'il n'était PAS protégé. J'ai compris comment fonctionne @property. Mais je ne comprends toujours pas quel est l'avantage de l'utiliser dans l'exemple ci-dessus