2010-02-02 7 views
1

classe A: def __get (auto): retour self._xSuppression des attributs lors de la suppression par exemple

def __set(self, y): 
    self._x = y 

def __delete_x(self): 
    print('DELETING') 
    del self._x 

x = property(__get,__set,__delete_x) 

b = A() 

# Here, when b is deleted, i'd like b.x to be deleted, i.e __delete_x() 
# called (and for immediate consequence, "DELETING" printed) 
del b 

Répondre

1

Pour contrôler ce qui se passe quand une instance de la classe A disparaît (que ce soit en cours de suppression ou de déchets collectés), vous pouvez implémenter la méthode spéciale __del__(self) dans A. Si vous voulez que votre code soit impliqué quand un attribut de cette instance disparaît, vous pouvez soit envelopper cet attribut avec une classe wrapper qui a __del__, soit, mieux dans la plupart des cas, utiliser le module weakref (mais pas tous les types sont sujets à être la cible de références faibles, donc vous aurez peut-être aussi besoin d'un emballage pour ce cas). Éviter __del__ est généralement préférable, si vous le pouvez, car il peut interférer avec la collecte des ordures et provoquer ainsi des «fuites de mémoire» si et quand vous avez des références circulaires.

2

La sémantique de l'instruction del ne se prête pas vraiment à ce que vous voulez ici. del b supprime simplement la référence à l'objet A que vous venez d'instancier dans le cadre/dictionnaire de portée locale; cela ne provoque pas directement une opération sur l'objet lui-même. Si c'était la dernière référence à l'objet, alors le compte de référence tombant à zéro, ou le garbage collector rassemblant un cycle, peut libérer l'objet. Vous pouvez observer cela en ajoutant une méthode __del__ à l'objet ou en ajoutant un rappel weakref qui effectue les actions souhaitées.

Cependant, aucune de ces deux solutions ne semble être une bonne idée. Les méthodes __del__ empêchent le collecteur d'ordures de recueillir des cycles quelconques impliquant l'objet; et tandis que weakrefs ne souffrent pas de ce problème, dans les deux cas, vous pouvez être dans un environnement étrange (comme lors de l'arrêt du programme), ce qui peut rendre difficile la réalisation de ce que vous voulez accomplir. Si vous pouvez développer votre cas d'utilisation exact, il se peut qu'il existe une approche totalement différente pour atteindre votre objectif final, mais il est difficile de spéculer sur la base d'un exemple aussi général et limité.

+0

Pas d'info vraiment assez pour constituer une réponse, mais ne pas oublier que ce ne soit pas effacé lorsque vous appelez 'del whatever', qui vient Enlève quoi que ce soit de ce qu'il pointe, il n'est supprimé que lorsqu'il n'y a plus de références à l'objet. – richo

0

Une façon laide de le faire serait:

def __del__(self): 
    for x in dir(self.__class__): 
     if type(getattr(self.__class__, x)) == property: 
      getattr(self.__class__, x).fdel(self) 
Questions connexes