9
votes

Variables d'instance constante?

J'utilise @property pour vous assurer que les modifications apportées à des variables d'instance d'objets sont enveloppées par des méthodes où j'ai besoin.

Qu'en est-il du moment où une instance a une variable qui ne devrait pas être changée logiquement? Par exemple, si je fais une classe pour un processus, chaque instance de processus devrait avoir un attribut PID qui sera fréquemment accessible mais ne devrait pas être modifié.

Quelle est la manière la plus pythonique de gérer quelqu'un qui tente de modifier cette variable d'instance?

  • Faites simplement confiance à l'utilisateur de ne pas essayer de changer quelque chose qu'ils ne devraient pas?

  • Utilisez la propriété mais soulevez un exception si la variable d'instance est modifié?

  • quelque chose d'autre?


4 Réponses :


1
votes

Peut-être que vous pouvez remplacer __ setattr __ ? Dans la ligne de, xxx


0 commentaires

9
votes

Préparez le nom de la variable avec __ code> et créez une propriété en lecture seule, Python s'occupera des exceptions et une variable elle-même sera protégée contre l'écrasement accidentel.

class foo(object):
    def __init__(self, bar):
        self.__bar = bar

    @property
    def bar(self):
        return self.__bar

f = foo('bar')
f.bar         # => bar
f.bar = 'baz' # AttributeError; would have to use f._foo__bar


3 commentaires

Dans les deux dernières lignes, vous voulez dire "f.foo" et "f.foo = 'baz" ", non?


Je trouve les attributs "Private" de noms-manqué pour être plus de problèmes que ce qu'ils vaut la peine. Un seul soulignement facilitera le sous-classement tout en communiquant «Ne touchez pas cela» aux utilisateurs.


Le problème avec des noms non mutilés est qu'ils peuvent être accidentellement écrasés dans des sous-classes. Étant donné que ces champs ne font pas partie de votre API publique, les clients de l'API ne devraient pas être tenus de prendre conscience des noms de vos champs «privés», mais ils doivent le faire de toute façon, car sinon, ils risquent de casser votre classe. Et, bien sûr, si, dans une nouvelle version de la classe, vous introduisez un nouveau champ, vous pouvez casser les clients existants contenant des sous-classes qui utilisent déjà le même nom de champ. La version mutilée a toujours tous ces problèmes, mais il réduit beaucoup les probabilités.



3
votes

Il suffit de faire confiance à l'utilisateur n'est pas nécessairement une mauvaise chose; Si vous écrivez simplement un programme de python rapide à utiliser une fois et que vous vous étiez bien jeté, vous pourriez très bien faire confiance à celui de l'utilisateur qui ne modifie pas le champ PID.

IMHO Le moyen le plus pythonique d'appliquer le champ en lecture seule est d'utiliser une propriété qui soulève une exception pour tenter de définir le champ.

Alors, monsieur, vous avez de bons instincts à ce sujet.


0 commentaires

1
votes

Utilisez simplement une propriété et un attribut caché (préfixé avec un em> Undercore).

Les propriétés simples sont en lecture seule! P>

>>> class Test (object):
...  @property
...  def bar(self):
...   return self._bar
... 
>>> t = Test()
>>> t._bar = 2
>>> t.bar
2
>>> t.bar = 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute


0 commentaires