2016-07-29 6 views
2

Я читал, что метод __ enter __ вводит __() и __ exit __(), каждый раз используется «с». Я понимаю, что для пользовательских объектов вы можете сами определить эти методы, но я не понимаю, как это работает для встроенных объектов/функций, таких как «open» или даже testcases.Где находится объект __enter __enter() __enter __enter(), созданный на Python, и __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

Так как же «открыто» работать с «с»? Должны ли объекты, поддерживающие протокол управления контекстом, __ вводить методы __() и __ exit __(), определенные и проверяемые?

+2

Пожалуйста, не используйте скриншоты для публикации текста. – Elizafox

+6

Попробуйте '' __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