Python';与';不删除对象
正在尝试正确删除Python对象。我正在创建一个对象,然后用“with”语句删除它。但当我在“with”语句关闭后打印时。。。。该对象仍然存在:Python';与';不删除对象,python,with-statement,Python,With Statement,正在尝试正确删除Python对象。我正在创建一个对象,然后用“with”语句删除它。但当我在“with”语句关闭后打印时。。。。该对象仍然存在: class Things(object): def __init__(self, clothes, food, money): self.clothes = clothes self.food = food self.money = money def __enter__(self):
class Things(object):
def __init__(self, clothes, food, money):
self.clothes = clothes
self.food = food
self.money = money
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('object deleted')
with Things('socks','food',12) as stuff:
greg = stuff.clothes
print(greg)
print(stuff.clothes)
返回:
socks
object deleted
socks
with
在退出块的作用域时调用对象的退出方法。您的\uuuuuuuuuuuuuuuuuuuuuuuuuu
方法所做的只是打印对象\u已删除
。实际上,您必须将用于销毁对象的代码放在\uuuuu exit\uuuu
方法中(但请注意,这不是一个好的做法!)
发生的情况是:
with Things('socks','food',12) as stuff:
# the __enter__() method is called and the returned object
# is assigned to the variable "stuff"
greg = stuff.clothes
print(greg)
# when you've exited the block here, the __exit__() method is called.
关于显式删除对象的愿望,您应该将其留给Python的垃圾收集器。读一下这个,它会有帮助的。您可以尝试使用或重写方法。以下是。Python的with
语句不是关于删除对象的,而是关于资源管理的。\uuuuuuuuuuuuu进入
和\uuuuuuu退出
方法用于提供资源初始化和销毁代码,即您可以选择删除其中的某些内容,但不会隐式删除对象。阅读一下这篇文章,更好地理解如何使用它
对象保留在with
语句之后的范围内。如果您需要的话,可以在上面调用del
。因为它在范围内,所以可以在关闭它的基础资源后查询它。考虑这个伪代码:
class DatabaseConnection(object):
def __init__(self, connection):
self.connection = connection
self.error = None
def __enter__(self):
self.connection.connect()
def __exit__(self, exc_type, exc_val, exc_tb):
self.connection.disconnect()
def execute(self, query):
try
self.connection.execute(query)
except e:
self.error = e
with DatabaseConnection(connection) as db:
db.execute('SELECT * FROM DB')
if db.error:
print(db.error)
del db
我们不希望数据库连接的挂起时间超过我们需要的时间(另一个线程/客户机可能需要它),因此我们允许释放资源(隐式地在with
块的末尾),但之后我们可以继续查询对象。然后,我添加了一个显式的del
,告诉运行时代码已使用变量完成
尝试正确删除Python对象
这是您的第一个错误,解释语言使您不必担心删除对象以释放内存。它们所做的是在没有更多引用且对象不再在范围内时删除它们
第二:
with Things('socks','food',12) as stuff:
greg = stuff.clothes
print(greg)
使用带有
的,尽管缩进
将代码与以下内容进行对比:
class Things(object):
def __init__(self, clothes, food, money):
self.clothes = clothes
self.food = food
self.money = money
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('object deleted')
stuff = "no stuff"
def do_it():
with Things('socks','food',12) as stuff:
greg = stuff.clothes
print(greg)
print(stuff)
do_it()
print(stuff)
其中:
socks
<__main__.Things object at 0xb744370c>
object deleted
no stuff
袜子
对象删除
没有东西
在这里,do_it()
中的内部stuff
不再存在,因此当第二个打印(stuff)
运行时,会出现“no stuff”
最后,不要担心删除对象。它会发生的,管理它不是你的工作。所以,感谢大家提供的好链接。但我真的很想删除一个对象,而不是等待花哨的垃圾收集器。这起到了作用:
class Things(object):
def __init__(self,clothes, food, money):
self.clothes = clothes
self.food = food
self.money = money
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('nothing happens')
with Things('socks','food',12) as stuff:
print(stuff.clothes)
del stuff
print(stuff)
现在返回:
socks
nothing happens
Traceback (most recent call last):
File "/home/jeff/PycharmProjects/tensorflow_sandbox/main", line 36, in <module>
print(stuff)
NameError: name 'stuff' is not defined
袜子
什么也没发生
回溯(最近一次呼叫最后一次):
文件“/home/jeff/PycharmProjects/tensorflow_sandbox/main”,第36行,中
印刷品(材料)
NameError:未定义名称“stuff”
万岁!它被删除了嗯,它并不是100%正确的。您不能在@user3583384内删除self
。您正在执行要删除的对象的方法。但是您的代码非常简单,是否需要使用上下文管理器?为什么不:stuff=Things(…);格雷格=东西、衣服;印刷(格雷格);del stuff
?这就是我在回答中所说的-with
不会删除。如果要尝试“强制”删除,您仍然必须调用del
。您可以删除\uuuuu exit\uuuu
中对象的字段,但该对象仍在with
块之后的范围内。你已经在你的例子中看到了这一点。@ChuckLoganLim:你说过“[…]交给Python的垃圾收集器处理。”。实际上,在这种情况下,Python的引用计数机制将删除该对象。垃圾收集器甚至看不到它。@AlexTaylor:del
不会删除该对象del
将删除绑定到对象的名称,之后Python可能会删除它。Alex Taylor的答案是正确的。我想补充一点,因为Python具有自动内存管理(垃圾收集),所以您不必担心删除不再使用的对象。因此,为此目的使用上下文管理器是毫无意义的。另外,名为“stuff”的变量是由with
语句创建的,但正如您所观察到的,它会一直存在到脚本结束。如果您有一行del stuff
,那么名称“stuff”将变得未定义。您可能需要这样做。可能的副本可能会考虑有<代码> PistMasks<代码>,它有一个<代码> .yEngulix方法创建并返回一个<代码>文件对象和一个<代码>