Python对象删除自身
为什么这样不行?我试图让一个类的实例删除它自己Python对象删除自身,python,memory-management,instance,Python,Memory Management,Instance,为什么这样不行?我试图让一个类的实例删除它自己 >>> class A(): def kill(self): del self >>> a = A() >>> a.kill() >>> a <__main__.A instance at 0x01F23170> >A类() def杀死(自我): 德尔赛尔夫 >>>a=a() >>>a.杀死 >>>a “self”只是对对象的引用“de
>>> class A():
def kill(self):
del self
>>> a = A()
>>> a.kill()
>>> a
<__main__.A instance at 0x01F23170>
>A类()
def杀死(自我):
德尔赛尔夫
>>>a=a()
>>>a.杀死
>>>a
“self”只是对对象的引用“del self”是从kill函数的本地命名空间而不是实际对象中删除“self”引用
要亲自了解这一点,请查看执行这两个函数时会发生什么:
>>> 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
>A类()
... def kill_a(自身):
... 打印自我
... 德尔赛尔夫
... def kill_b(自身):
... 德尔赛尔夫
... 打印自我
...
>>>a=a()
>>>b=A()
>>>a.杀死
>>>b.杀死
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第7行,在kill_b中
UnboundLocalError:赋值前引用的局部变量“self”
首先不需要使用del来删除实例。一旦对对象的最后一次引用消失,该对象将被垃圾收集。也许您应该告诉我们更多关于完整问题的信息。事实上,Python通过引用计数进行垃圾收集。一旦对象的最后一个引用超出范围,它就会被删除。在您的示例中:
a = A()
a.kill()
我不相信有任何方法可以让变量“a”隐式地将自己设置为“无”。我很好奇为什么您会想做这样的事情。很可能,您应该让垃圾收集完成它的工作。在python中,垃圾收集是非常确定的。因此,您不必像在其他语言中那样担心将对象留在内存中(更不用说重计数没有缺点)
虽然你应该考虑的是一个包装,你可以在以后清除任何对象或资源。
class foo(object):
def __init__(self):
self.some_big_object = some_resource
def killBigObject(self):
del some_big_object
针对:
不幸的是,我不相信有一种方法可以按照你想的方式去做你想做的事情。以下是您可能希望考虑的一种方法:
>>> class manager(object):
... def __init__(self):
... self.lookup = {}
... def addItem(self, name, item):
... self.lookup[name] = item
... item.setLookup(self.lookup)
>>> class Item(object):
... def __init__(self, name):
... self.name = name
... def setLookup(self, lookup):
... self.lookup = lookup
... def deleteSelf(self):
... del self.lookup[self.name]
>>> man = manager()
>>> item = Item("foo")
>>> man.addItem("foo", item)
>>> man.lookup
{'foo': <__main__.Item object at 0x81b50>}
>>> item.deleteSelf()
>>> man.lookup
{}
类管理器(对象):
... 定义初始化(自):
... self.lookup={}
... def附加项(自身、名称、项目):
... self.lookup[名称]=项
... item.setLookup(self.lookup)
>>>类别项目(对象):
... 定义初始化(self,name):
... self.name=名称
... def setLookup(自我,查找):
... self.lookup=查找
... def deleteSelf(self):
... del self.lookup[self.name]
>>>经理
>>>项目=项目(“foo”)
>>>man.addItem(“foo”,项目)
>>>男人,查寻
{'foo':}
>>>item.deleteSelf()
>>>男人,查寻
{}
这有点凌乱,但这应该让你明白了。从本质上说,我不认为将一个项目在游戏中的存在与它是否在内存中分配联系起来是一个好主意。这是因为垃圾收集物品的条件可能与游戏中物品的条件不同。这样,你就不必太担心了。在这个特定的上下文中,你的例子没有多大意义 当一个生物捡起一个物品时,该物品保持着个体的存在。它不会因为被捡到而消失。它仍然存在,但它(a)与存在物位于同一位置,并且(b)不再有资格被拾取。虽然它的状态发生了变化,但它仍然存在 存在与项目之间存在双向关联。存在者在集合中具有该项。该项与存在关联 当一个生物捡起一件物品时,必须发生两件事
- 如何在项目的某些
集合中添加项目。例如,您的
属性可以是这样一个包
。[A集
是一个糟糕的选择——订单在袋子里重要吗?]列表
- 物品的位置从原来的位置更改为存在者的位置。可能有两类操作系统项目——一类是具有独立位置感的项目(因为它们自己移动),另一类是必须将位置委托给存在者或它们所在的位置的项目
player.bag.remove(cat)
这是泄露秘密所需要的一切。由于cat不在其他任何地方使用,它将作为“已用”内存存在,并且不存在,因为程序中没有任何内容可以访问它。当一些量子事件发生并且内存引用被垃圾收集时,它将从内存中悄然消失
另一方面,
here.add( cat )
player.bag.remove(cat)
将使cat处于当前位置。cat仍然存在,不会与垃圾一起被丢弃。我无法告诉您如何在类中实现这一点,但函数可以删除它们自己
def kill_self(exit_msg = 'killed'):
global kill_self
del kill_self
return exit_msg
并查看输出:
>>> kill_self
<function kill_self at 0x02A2C780>
>>> kill_self()
'killed'
>>> kill_self
Traceback (most recent call last):
File "<pyshell#28>", line 1, in <module>
kill_self
NameError: name 'kill_self' is not defined
杀死自己
>>>自杀
“被杀”
>>>自杀
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
自杀
NameError:未定义名称“kill_self”
我认为在不知道类的名称的情况下删除单个类实例是不可能的
注意:
如果为函数指定了另一个名称,则另一个名称仍将引用旧名称,但在尝试运行该名称时会导致错误:
>>> x = kill_self
>>> kill_self()
>>> kill_self
NameError: name 'kill_self' is not defined
>>> x
<function kill_self at 0x...>
>>> x()
NameError: global name 'kill_self' is not defined
>>x=kill\u self
>>>自杀
>>>自杀
NameError:未定义名称“kill_self”
>>>x
>>>x()
NameError:未定义全局名称“kill_self”
我也在尝试同样的事情。我有一个RPG战斗系统,在这个系统中,我的死亡(自我)功能必须杀死战士类自己的目标。但这似乎是不可能的。也许我收集所有战斗参与者的班级游戏应该从“虚拟”地图中删除单位
def Death(self):
如果self.stats[“HP”]=0:
敌人。属性[“生命”]-=伤害
打印(“%s在您的攻击中受到了%d点伤害!”%(敌方玩家[“Name”],todamage)
def Death(self):
if self.stats["HP"] <= 0:
print("%s wounds were too much... Dead!"%(self.player["Name"]))
del self
else:
return True
def Damage(self, enemy):
todamage = self.stats["ATK"] + randint(1,6)
todamage -= enemy.stats["DEF"]
if todamage >=0:
enemy.stats["HP"] -= todamage
print("%s took %d damage from your attack!"%(enemy.player["Name"], todamage))
enemy.Death()
return True
else:
print("Ineffective...")
return True
def Attack(self, enemy):
tohit = self.stats["DEX"] + randint(1,6)
if tohit > enemy.stats["EVA"]:
print("You landed a successful attack on %s "%(enemy.player["Name"]))
self.Damage(enemy)
return True
else:
print("Miss!")
return True
def Action(self, enemylist):
for i in range(0, len(enemylist)):
print("No.%d, %r"%(i, enemylist[i]))
print("It`s your turn, %s. Take action!"%(self.player["Name"]))
choice = input("\n(A)ttack\n(D)efend\n(S)kill\n(I)tem\n(H)elp\n>")
if choice == 'a'or choice == 'A':
who = int(input("Who? "))
self.Attack(enemylist[who])
return True
else:
return self.Action()
class Zero:
pOne = None
class One:
pTwo = None
def process(self):
self.pTwo = Two()
self.pTwo.dothing()
self.pTwo.kill()
# now this fails:
self.pTwo.dothing()
class Two:
def dothing(self):
print "two says: doing something"
def kill(self):
Zero.pOne.pTwo = None
def main():
Zero.pOne = One() # just a global
Zero.pOne.process()
if __name__=="__main__":
main()
if object_exists:
use_existing_obj()
else:
obj = Obj()
class A:
def __init__(self, name):
self.name=name
def kill(self)
del dict[self.name]
dict={}
dict["a"]=A("a")
dict["a"].kill()
# 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
>>> 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
class A:
def __init__(self, function):
self.function = function
def kill(self):
self.function(self)
def delete(object): #We are no longer in A object
del object
a = A(delete)
print(a)
a.kill()
print(a)
bullet_list = []
class Bullet:
def kill_self(self):
bullet_list.remove(self)
bullet_list += [Bullet()]
class A:
def __init__(self):
self.a = 123
def kill(self):
from itertools import chain
for attr_name in chain(dir(self.__class__), dir(self)):
if attr_name.startswith('__'):
continue
attr = getattr(self, attr_name)
if callable(attr):
setattr(self, attr_name, lambda *args, **kwargs: print('NoneType'))
else:
setattr(self, attr_name, None)
a.__str__ = lambda: ''
a.__repr__ = lambda: ''
a = A()
print(a.a)
a.kill()
print(a.a)
a.kill()
a = A()
print(a.a)
123
None
NoneType
123