Python 内置对象的 __enter__() 和 __exit__() 在哪里定义?
Where is a Python built-in object's __enter__() and __exit__() defined?
我读到,每次使用 'with' 时都会调用对象的 __ enter__() 和 __ exit__() 方法。我知道对于用户定义的对象,您可以自己定义这些方法,但我不明白这对于像 'open' 甚至测试用例这样的内置 objects/functions 是如何工作的。
此代码按预期工作,我假设它使用 __ exit__():
关闭文件
with open('output.txt', 'w') as f:
f.write('Hi there!')
或
with self.assertRaises(ValueError):
remove_driver(self.driver) # self refers to a class that inherits from the default unittest.TestCase
然而,当我检查它时,这两个对象上都没有这样的 __ enter__() 或 __ exit__() 方法:
那么 'open' 如何与 'with' 一起工作?支持上下文管理协议的对象不应该定义和检查 __ enter__() 和 __ exit__() 方法吗?
您正在检查 open
函数本身或 assertRaises
方法本身是否具有 __enter__
和 __exit__
方法,而您应该查看哪些方法return 值有。
open
是 return 具有上下文方法的文件对象的函数,self.assertRaises
是 return 具有上下文方法的对象的方法,尝试检查其 return 值的 dir
:
>>> x = open(__file__, "r")
>>> x
<_io.TextIOWrapper name='test.py' mode='r' encoding='US-ASCII'>
>>> type(x)
<class '_io.TextIOWrapper'>
>>> "__exit__" in dir(x)
True
open()
是一个函数。它 returns 具有 __enter__
和 __exit__
方法的东西。看看这样的东西:
>>> class f:
... def __init__(self):
... print 'init'
... def __enter__(self):
... print 'enter'
... def __exit__(self, *a):
... print 'exit'
...
>>> with f():
... pass
...
init
enter
exit
>>> def return_f():
... return f()
...
>>> with return_f():
... pass
...
init
enter
exit
当然,return_f
本身没有这些方法,但是returns有。
我读到,每次使用 'with' 时都会调用对象的 __ enter__() 和 __ exit__() 方法。我知道对于用户定义的对象,您可以自己定义这些方法,但我不明白这对于像 'open' 甚至测试用例这样的内置 objects/functions 是如何工作的。
此代码按预期工作,我假设它使用 __ exit__():
关闭文件with open('output.txt', 'w') as f:
f.write('Hi there!')
或
with self.assertRaises(ValueError):
remove_driver(self.driver) # self refers to a class that inherits from the default unittest.TestCase
然而,当我检查它时,这两个对象上都没有这样的 __ enter__() 或 __ exit__() 方法:
那么 'open' 如何与 'with' 一起工作?支持上下文管理协议的对象不应该定义和检查 __ enter__() 和 __ exit__() 方法吗?
您正在检查 open
函数本身或 assertRaises
方法本身是否具有 __enter__
和 __exit__
方法,而您应该查看哪些方法return 值有。
open
是 return 具有上下文方法的文件对象的函数,self.assertRaises
是 return 具有上下文方法的对象的方法,尝试检查其 return 值的 dir
:
>>> x = open(__file__, "r")
>>> x
<_io.TextIOWrapper name='test.py' mode='r' encoding='US-ASCII'>
>>> type(x)
<class '_io.TextIOWrapper'>
>>> "__exit__" in dir(x)
True
open()
是一个函数。它 returns 具有 __enter__
和 __exit__
方法的东西。看看这样的东西:
>>> class f:
... def __init__(self):
... print 'init'
... def __enter__(self):
... print 'enter'
... def __exit__(self, *a):
... print 'exit'
...
>>> with f():
... pass
...
init
enter
exit
>>> def return_f():
... return f()
...
>>> with return_f():
... pass
...
init
enter
exit
当然,return_f
本身没有这些方法,但是returns有。