Python'with'不删除对象

rik*_*mbo 9 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):
       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)
Run Code Online (Sandbox Code Playgroud)

回报:

socks
object deleted
socks
Run Code Online (Sandbox Code Playgroud)

Ale*_*lor 20

Python的with声明不是关于删除对象 - 它是关于资源管理的.该__enter____exit__方法,为您提供资源的初始化和销毁的代码,即可以选择删除的东西在那里,但对象的隐式删除.阅读with本文以更好地理解如何使用它.

该对象在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
Run Code Online (Sandbox Code Playgroud)

我们不希望保持数据库连接的挂起时间比我们需要的时间长(另一个线程/客户端可能需要它),所以我们允许释放资源(隐式地在with块的末尾),但是我们可以继续在那之后查询对象.然后我添加了一个显式del来告诉运行时代码已完成变量.


Chu*_*Lim 5

with__exit__在退出块的范围时调用对象的方法.你的__exit__方法做的只是打印object_deleted.你必须实际放置代码来破坏你__exit__方法中的对象(但请注意,这不是好习惯!).

会发生什么:

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.
Run Code Online (Sandbox Code Playgroud)

关于你明确删除对象的愿望,你应该把它留给Python的垃圾收集器.阅读这个问题,它会有所帮助.您可以尝试使用gc.collect()或覆盖该__del__方法.这是另一个很好的讨论.

  • @AlexTaylor:`del`不会删除该对象.`del`将删除绑定到该对象的名称,之后Python _might_将其删除. (2认同)