Python 使用语句,自动删除对象
是否可以删除其类中的对象窗体Python 使用语句,自动删除对象,python,with-statement,object-destruction,Python,With Statement,Object Destruction,是否可以删除其类中的对象窗体 class A(): def __init__(self): print("init") self.b="c" def __enter__(self): print("enter") return self def __exit__(self, type, value, traceback): print("exit") with A() as a:
class A():
def __init__(self):
print("init")
self.b="c"
def __enter__(self):
print("enter")
return self
def __exit__(self, type, value, traceback):
print("exit")
with A() as a:
print(a.b)
print(a.b)
返回:
init
enter
c
exit
c
在使用退出后,我如何仍然可以访问对象?是否有方法自动删除
\uuu exit\uuu
中的对象?是和否。在with
子句后面使用dela
。这将删除对象上最后一个引用持有者的变量a
对象本身(即在\uuuuu exit\uuuu()
中)不能让知道它并持有引用的人(即with
子句中的代码)忘记这一点。只要引用存在,对象就会存在
当然,您的对象可以在\uuuu exit\uuuu()
中清空自身,并保持为空心对象(例如,在本例中,通过del self.b
)
不能在\uuuu exit\uuuu
中删除类A本身的实例。您最多只能删除属性b
init
enter
c
exit
Traceback (most recent call last):
File "main.py", line 14, in <module>
print(a.b)
AttributeError: A instance has no attribute 'b'
init
进入
C
出口
回溯(最近一次呼叫最后一次):
文件“main.py”,第14行,在
印刷品(a.b)
AttributeError:实例没有属性“b”
简短回答:这(在某种程度上)是可能的,但根本不可取
Python中的with
部分没有专用的作用域,因此这意味着with
语句中定义的变量不会被删除。这是经常需要的行为。例如,如果加载一个文件,您可以这样编写:
with open('foo.txt') as f:
data = list(f)
print(data)
>>> with A() as a:
... pass
...
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
# If A.__enter__ returns an iterable with two elements
with A() as (foo, bar):
pass
您不想删除数据
变量:此处使用with
来确保文件处理程序正确关闭(如果with
的主体中发生异常,处理程序也会关闭)
严格来说,您可以通过“黑客”解决方案删除引用A()
对象的局部变量:我们检查调用堆栈,删除对self
(或其他对象)的引用,如:
因此,这些元素将不会得到回收。最后,如果\uuuuu enter\uuuuuu
返回self
,则它可能“删除太多”,因为可以使用foo作为bar编写,然后foo
和bar
都将被删除
无论如何,大多数IDE可能无法理解\uuuuu exit\uuuuu
中的逻辑,因此仍然会在自动完成中包含a
一般来说,最好简单地将对象标记为已关闭,如:
import inspect
class A(object):
def __init__(self):
self.closed = False
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.closed = True
def some_method(self):
if self.closed:
raise Exception('A object is closed')
# process request
上述也是文件处理程序处理它的方式。带有的没有定义特定的范围,因此您可以在定义变量后使用这些变量。是的,但是在退出时不可能这样做吗?如果用户只能用“with”打开我的应用程序,而没有访问权限,那么对我的应用程序来说会更安全afterward@RémiBaudoux:您可以更改对象的状态,使其不再“可访问”(就像文件处理程序一样,在with
语句中,文件处理程序关闭,但变量仍然存在),删除itI实际上是有道理的,你必须“在”对象之外。我刚刚注意到,你甚至可以在exit中删除方法,这很有用,不是删除,而是通过执行以下操作来禁用访问:self.my_method=None
谢谢你的准确性!我想我会删除出口中的所有变量和方法,例如,如果我试图访问类中的任何内容,它本身会引发错误。@RémiBaudoux,但请注意,这不是非常Pythonic的。下一个开发人员(或库的用户)可能会对这种行为感到非常惊讶。
# If A.__enter__ returns an iterable with two elements
with A() as (foo, bar):
pass
import inspect
class A(object):
def __init__(self):
self.closed = False
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.closed = True
def some_method(self):
if self.closed:
raise Exception('A object is closed')
# process request