2012-06-14 3 views
2

Parfois, j'ai besoin de changer le nom d'un attribut de classe Python qui est déjà largement utilisé dans le reste du code.Comment gérer les affectations d'attributs errants python

Le problème est que, pour diverses raisons, certains endroits où l'ancien nom apparaît dans une instruction d'affectation comme class_instance.old_attribute_name = something peuvent me manquer. Par exemple:

class theClass: 
    def __init__(self): 
     self.new_attribute_name = 0 

o = theClass() 
o.new_attribute_name += 3 
if o.new_attribute_name > 3 or o.new_attribute_name < 4: 
    o.old_attribute_name = 7 
do_stuff_with(o.new_attribute_name) 

Le problème est que cela peut être difficile à repérer, augmentera pas d'erreur et il suffit de créer un attribut inutile. J'ai envisagé d'utiliser __slot__, mais j'ai envie de forcer mon état d'esprit C/C++ profond sur Python.

Donc, je voudrais demander, qu'est-ce que je fais mal ici? Que vais-je perdre si j'essaie (en quelque sorte) d'empêcher la création d'attributs en dehors de l'instanciation? Quelle est la manière pythonique de gérer les affectations d'attributs parasites?

Répondre

3

Vous pouvez faire l'ancien nom d'attribut une propriété

class theClass(object): 
    def __init__(self): 
     self.new_attribute_name = 0 

    @property 
    def old_attribute_name(self): 
     print "Tried to access old_attribute_name" 
     return self.new_attribute_name 

    @old_attribute_name.setter 
    def old_attribute_name(self, value): 
     print "Tried to set old_attribute_name" 
     return self.new_attribute_name 
+0

Je note que je ferais cela (personnellement, je jetterais une exception plutôt que l'impression) de débogage, afin d'assurer l'ancien code a été traité, puis retirez une fois cela fait. –

+1

Idéalement, vous devriez utiliser "warnings.warn" avec "DeprecationWarning" pour pouvoir contrôler si l'accès à l'ancien nom déclenche une exception ou imprime simplement un avertissement à la sortie standard. – lunaryorn

0

Au lieu d'essayer de trouver tous les endroits que vous devez changer avec la recherche et de remplacement, vous pouvez plutôt essayer un outil « refactoring ».

What refactoring tools do you use for Python?

+0

Notez qu'en raison de la nature dynamique de Python, les outils de refactoring ne peuvent pas capturer toutes les possibilités d'accès aux attributs, et donc probablement manquer les noms utilisés dans le code polymorphe ou accédés dynamiquement (ie getattr() '). – lunaryorn

+0

@lunaryorn, en effet. Mais cela ne rend pas totalement inutiles de tels outils. Il y a beaucoup de code Python qui n'est pas très dynamique –

+0

@gnibbler N'a pas dit autre chose. La corde est un outil bon et important, mais gardez juste à l'esprit qu'il pourrait manquer des occurrences lors du refactoring. Vérifiez ensuite les sources par la suite, et bénéficiez d'une bonne couverture de test avant de commencer. – lunaryorn

0

Vous pouvez le faire avec la propriété. Il bloquera à la fois l'obtention et le réglage de l'ancien nom d'attribut.

class A(object): 
    @property 
    def old_name(self): 
     raise NotImplementedError() 
Questions connexes