2016-07-29 37 views
2

我读过对象的__输入__()和__ exit __()方法,每次使用'with'时都会被调用。我明白,对于用户定义的对象,你可以自己定义这些方法,但我不明白这是如何工作的内置对象/功能,如“开放”,甚至测试案例。Python内置对象的__enter __()和__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 image description here

enter image description here

那么'open'是如何与'with'一起工作的呢?不应该支持上下文管理协议的对象有__输入__()和__退出__()方法定义和可检查?

+2

请不要使用屏幕截图来共享文本。 – Elizafox

+6

在dir中打开''__exit__'(open('/ dev/null'))' – robyschek

+2

'open'不是支持上下文管理器协议的对象。它的*返回值*是支持该协议的对象。同样,对于'assertRaises'。 – BrenBarn

回答

8

open()是一个函数。它返回东西有一个__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本身不具有这些方法,但它返回什么呢。

2

您正在检查open函数本身或assertRaises方法本身是否有__enter____exit__方法,您应该查看返回值具有哪些方法。

5

open是返回一个文件对象与上下文方法的函数,self.assertRaises是与上下文方法返回一个对象的方法,尝试检查其返回值的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