Python 객체 자체 삭제
왜 작동하지 않습니까? 클래스의 인스턴스를 스스로 삭제하려고합니다.
>>> class A():
def kill(self):
del self
>>> a = A()
>>> a.kill()
>>> a
<__main__.A instance at 0x01F23170>
'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
처음에 인스턴스를 삭제하기 위해 del을 사용할 필요가 없습니다. 객체에 대한 마지막 참조가 사라지면 객체는 가비지 수집됩니다. 전체 문제에 대해 더 자세히 알려 주셔야합니다.
이 특정 맥락에서 귀하의 예는 그다지 의미가 없습니다.
존재가 항목을 집을 때 항목은 개별 존재를 유지합니다. 주워서 사라지지 않습니다. 여전히 존재하지만 (a) 존재와 동일한 위치에 있으며 (b) 더 이상 픽업 할 자격이 없습니다. 상태가 변경되었지만 여전히 존재합니다.
존재와 항목 사이에는 양방향 연결이 있습니다. 존재는 컬렉션에 아이템을 가지고 있습니다. 항목은 존재와 연관됩니다.
한 존재가 아이템을 집어 들면 두 가지 일이 일어나야합니다.
존재 방법은 일부 항목에 항목을 추가합니다
set
.bag
예를 들어 귀하의 속성은 그러한set
. [Alist
는 잘못된 선택입니다. 주문이 가방에 들어가는 것이 중요합니까?]아이템의 위치는 이전 위치에서 존재의 위치로 변경됩니다. 아마도 두 개의 클래스 os Items가있을 것입니다-독립적 인 위치 감각을 가진 것들 (스스로 주위를 움직이기 때문에)과 위치를 자신이 앉아있는 존재 또는 장소에 위임해야하는 항목.
어떤 상황에서도 Python 객체를 삭제할 필요가 없습니다. 아이템이 "파괴"되었다면 그것은 존재의 가방에 있지 않습니다. 위치에 없습니다.
player.bag.remove(cat)
고양이를 가방에서 꺼내는 데 필요한 전부입니다. 고양이는 다른 곳에서는 사용되지 않으므로 둘 다 "사용 된"메모리로 존재하고 프로그램의 어떤 것도 액세스 할 수 없기 때문에 존재하지 않습니다. 일부 퀀텀 이벤트가 발생하고 메모리 참조가 가비지 수집되면 메모리에서 조용히 사라집니다.
반면에
here.add( cat )
player.bag.remove(cat)
고양이를 현재 위치에 놓습니다. 고양이는 계속 존재하며 쓰레기와 함께 내놓지 않을 것입니다.
드디어 얻은 것 같아요!
참고 : 일반 코드 에서는 사용하지 않아야 하지만 가능합니다 . 이것은 호기심 일뿐입니다.이 문제에 대한 실제 솔루션에 대한 다른 답변을 참조하십시오.
이 코드를 살펴보십시오.
# 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
__new__
메서드 에서 개체가 생성 되면 인스턴스가 약한 참조 프록시로 대체되고 유일한 강력한 참조는 _alive 클래스 속성에 유지됩니다.
약한 참조 란 무엇입니까?
약한 참조는 가비지 수집기가 개체를 수집 할 때 참조로 계산되지 않는 참조입니다. 이 예를 고려하십시오.
>>> 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
따라서 인스턴스에 대한 유일한 강력한 참조는 _alive 클래스 속성에 저장됩니다. 그리고 commit_suicide () 메서드가 참조를 제거하면 인스턴스가 가비지 수집됩니다.
현실적으로 수행하려는 작업을 수행하기 위해 개체를 삭제할 필요는 없습니다. 대신 개체의 상태를 변경할 수 있습니다. 코딩에 들어 가지 않고 이것이 어떻게 작동하는지에 대한 예는 플레이어가 몬스터와 싸우고 몬스터를 죽이는 것입니다. 이 괴물의 상태는 싸우고 있습니다. 몬스터는 전투에 필요한 모든 방법에 접근 할 것입니다. 몬스터의 체력이 0이되어 죽으면 몬스터 상태가 죽은 상태로 바뀌고 캐릭터는 자동으로 공격을 멈 춥니 다. 이 방법론은 플래그 또는 키워드를 사용하는 것과 매우 유사합니다.
또한 파이썬에서는 클래스를 더 이상 사용하지 않을 때 자동으로 가비지 수집되므로 클래스를 삭제할 필요가 없습니다.
클래스에서 이것이 어떻게 가능한지 말할 수는 없지만 함수는 스스로 삭제할 수 있습니다.
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
나는 클래스의 이름을 모른 채 클래스의 개별 인스턴스를 삭제할 수 있다고 생각하지 않습니다.
참고 : 함수에 다른 이름을 지정하면 다른 이름이 여전히 이전 이름을 참조하지만 실행을 시도하면 오류가 발생합니다.
>>> 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
나는 똑같은 것을 시도하고있다. 내 Death (self) 기능이 Fighter 클래스의 자체 개체를 죽여야하는 RPG 전투 시스템이 있습니다. 그러나 그것은 불가능한 것처럼 보였다. 전투에 참여하는 모든 참가자를 모으는 클래스 게임이 "가상"맵에서 유닛을 삭제해야할까요 ???
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()
실제로 Python은 참조 계산을 통해 가비지 수집을 수행합니다. 개체에 대한 마지막 참조가 범위를 벗어나는 즉시 삭제됩니다. 귀하의 예에서 :
a = A()
a.kill()
변수 'a'가 암시 적으로 없음으로 설정 될 수있는 방법이 없다고 생각합니다.
개체에 대한 단일 참조를 사용하는 경우 다음과 같이 외부 참조를 자신에 대해 재설정하여 개체가 스스로를 죽일 수 있습니다.
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()
I'm curious as to why you would want to do such a thing. Chances are, you should just let garbage collection do its job. In python, garbage collection is pretty deterministic. So you don't really have to worry as much about just leaving objects laying around in memory like you would in other languages (not to say that refcounting doesn't have disadvantages).
Although one thing that you should consider is a wrapper around any objects or resources you may get rid of later.
class foo(object):
def __init__(self):
self.some_big_object = some_resource
def killBigObject(self):
del some_big_object
In response to Null's addendum:
Unfortunately, I don't believe there's a way to do what you want to do the way you want to do it. Here's one way that you may wish to consider:
>>> 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
{}
It's a little bit messy, but that should give you the idea. Essentially, I don't think that tying an item's existence in the game to whether or not it's allocated in memory is a good idea. This is because the conditions for the item to be garbage collected are probably going to be different than what the conditions are for the item in the game. This way, you don't have to worry so much about that.
what you could do is take the name with you in the class and make a dictionairy:
class A:
def __init__(self, name):
self.name=name
def kill(self)
del dict[self.name]
dict={}
dict["a"]=A("a")
dict["a"].kill()
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)
May this code work ?
This is something I have done in the past. Create a list of objects, and you can then have objects delete themselves with the list.remove()
method.
bullet_list = []
class Bullet:
def kill_self(self):
bullet_list.remove(self)
bullet_list += [Bullet()]
참고URL : https://stackoverflow.com/questions/293431/python-object-deleting-itself
'development' 카테고리의 다른 글
후행 슬래시는 Flask 경로 규칙에서 404를 트리거합니다. (0) | 2020.12.03 |
---|---|
설치 후 Visual Studio 2017 커뮤니티를 시작할 때 "알 수없는 오류"발생 (0) | 2020.12.03 |
SVN에서 업데이트 할 때 항상 (강제) 로컬 변경 사항을 덮어 쓸 수 있습니까? (0) | 2020.12.03 |
쉘 스크립트를 사용하여 XML을 구문 분석하는 방법은 무엇입니까? (0) | 2020.12.03 |
자바 스크립트는 대소 문자를 구분하지 않고 문자열 비교 (0) | 2020.12.03 |