Pourquoi cela ne fonctionne-t-il pas ? J'essaie de faire en sorte qu'une instance d'une classe se supprime elle-même.
>>> class A():
def kill(self):
del self
>>> a = A()
>>> a.kill()
>>> a
<__main__.A instance at 0x01F23170>
Pourquoi cela ne fonctionne-t-il pas ? J'essaie de faire en sorte qu'une instance d'une classe se supprime elle-même.
>>> class A():
def kill(self):
del self
>>> a = A()
>>> a.kill()
>>> a
<__main__.A instance at 0x01F23170>
Le "self" n'est qu'une référence à l'objet. del self" supprime la référence "self" de l'espace de noms local de la fonction kill, au lieu de l'objet lui-même.
Pour s'en convaincre, il suffit de regarder ce qui se passe lorsque ces deux fonctions sont exécutées :
>>> class A():
... def kill_a(self):
... print self
... del self
... def kill_b(self):
... del self
... print self
...
>>> a = A()
>>> b = A()
>>> a.kill_a()
<__main__.A instance at 0xb771250c>
>>> b.kill_b()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in kill_b
UnboundLocalError: local variable 'self' referenced before assignment
Je crois que j'ai enfin trouvé !
NOTE : Vous ne devez pas utiliser cette fonction dans le code normal. mais c'est le cas possible . Il s'agit uniquement d'une curiosité, voir les autres réponses pour des solutions concrètes à ce problème.
Jetez un coup d'œil à ce code :
# NOTE: This is Python 3 code, it should work with python 2, but I haven't tested it.
import weakref
class InsaneClass(object):
_alive = []
def __new__(cls):
self = super().__new__(cls)
InsaneClass._alive.append(self)
return weakref.proxy(self)
def commit_suicide(self):
self._alive.remove(self)
instance = InsaneClass()
instance.commit_suicide()
print(instance)
# Raises Error: ReferenceError: weakly-referenced object no longer exists
Lorsque l'objet est créé dans le __new__
l'instance est remplacée par un proxy de référence faible et la seule référence forte est conservée dans l'attribut de classe _alive.
Une référence faible est une référence qui ne compte pas comme une référence lorsque le ramasse-miettes collecte l'objet. Prenons l'exemple suivant :
>>> class Test(): pass
>>> a = Test()
>>> b = Test()
>>> c = a
>>> d = weakref.proxy(b)
>>> d
<weakproxy at 0x10671ae58 to Test at 0x10670f4e0>
# The weak reference points to the Test() object
>>> del a
>>> c
<__main__.Test object at 0x10670f390> # c still exists
>>> del b
>>> d
<weakproxy at 0x10671ab38 to NoneType at 0x1002050d0>
# d is now only a weak-reference to None. The Test() instance was garbage-collected
La seule référence forte à l'instance est donc stockée dans l'attribut de classe _alive. Et lorsque la méthode commit_suicide() supprime la référence, l'instance est ramassée.
Dans ce contexte spécifique, votre exemple n'a pas beaucoup de sens.
Lorsqu'un Être ramasse un objet, celui-ci conserve une existence individuelle. Il ne disparaît pas parce qu'il a été ramassé. Il existe toujours, mais il est (a) au même endroit que l'Être, et (b) ne peut plus être ramassé. Bien qu'il ait changé d'état, il existe toujours.
Il existe une association bidirectionnelle entre l'être et l'objet. L'être possède l'objet dans une collection. L'objet est associé à un être.
Lorsqu'un objet est ramassé par un être, deux choses doivent se produire.
L'Être comment ajoute l'Élément dans certains set
d'articles. Votre bag
par exemple, pourrait être un tel attribut set
. [A list
est un mauvais choix -- l'ordre importe-t-il dans le sac ?].
L'emplacement de l'objet passe de l'endroit où il se trouvait à l'endroit où se trouve l'être. Il existe probablement deux catégories d'objets : ceux qui ont un sens indépendant de l'emplacement (parce qu'ils se déplacent par eux-mêmes) et ceux qui doivent déléguer leur emplacement à l'être ou au lieu où ils se trouvent.
En aucun cas un objet Python ne doit être supprimé. Si un objet est "détruit", il n'est pas dans le sac de l'Être. Il n'est pas dans un emplacement.
player.bag.remove(cat)
C'est tout ce qu'il faut pour que le chat sorte du sac. Puisque le chat n'est utilisé nulle part ailleurs, il existera à la fois en tant que mémoire "utilisée" et n'existera pas parce que rien dans votre programme ne peut y accéder. Il disparaîtra tranquillement de la mémoire lorsqu'un événement quantique se produira et que les références de la mémoire seront ramassées.
D'autre part,
here.add( cat )
player.bag.remove(cat)
Place le chat à l'emplacement actuel. Le chat continue d'exister et ne sera pas mis à la poubelle.
En réalité, vous ne devriez pas avoir besoin de supprimer l'objet pour faire ce que vous essayez de faire. Au lieu de cela, vous pouvez modifier l'état de l'objet. Pour illustrer ce principe sans entrer dans le codage, prenons l'exemple d'un joueur qui se bat contre un monstre et le tue. L'état de ce monstre est "fighting". Le monstre accède à toutes les méthodes nécessaires au combat. Lorsque le monstre meurt parce que sa santé tombe à 0, l'état du monstre passe à mort et votre personnage cesse automatiquement d'attaquer. Cette méthodologie est très similaire à l'utilisation de drapeaux ou même de mots-clés.
Apparemment, en Python, il n'est pas nécessaire de supprimer les classes, car elles sont automatiquement ramassées lorsqu'elles ne sont plus utilisées.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.