Python内置对象的__enter __()和__exit __()定义在哪里?

时间:2016-07-29 20:09:03

标签: python with-statement contextmanager code-inspection

我已经读过,每次使用'with'时,都会调用对象的__ enter __()和__ exit __()方法。我理解,对于用户定义的对象,您可以自己定义这些方法,但我不明白它如何适用于内置对象/函数,如“open”甚至是测试用例。

此代码按预期工作,我假设它使用__ 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 __()方法:

enter image description here

enter image description here

那么'打开'如何使用'with'?不应该支持上下文管理协议的对象__输入__()和__ exit __()方法定义和检查吗?

3 个答案:

答案 0 :(得分:10)

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本身没有这些方法,但它返回的是什么。

答案 1 :(得分: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

答案 2 :(得分:2)

您应该查看dt[order(group, -time) ][, groupP := shift(group, type='lag') ][, head := is.na(groupP) | group != groupP ][, copy(.SD)[.SD[head == T], rTime := i.time, on=c(group='group')] ][time > (rTime - 24*60*60) ][, .(group, time) ][order(group, -time) ] group time 1: 1 2016-03-09 13:31:00 2: 1 2016-03-08 16:31:00 3: 2 2016-04-11 03:28:00 4: 3 2016-05-11 23:52:00 5: 3 2016-05-11 00:52:00 > 函数本身或open方法本身是否有assertRaises__enter__方法,当您应该查看哪些方法时返回值有。