Могу ли я написать функцию, которая определяет, вызывается ли она из оператора with или нет? - PullRequest
1 голос
/ 15 января 2011

Точнее, могу ли я определить, вызывается ли функция как EXPR в with EXPR: BLOCK выражении? Я пытаюсь ознакомиться с использованием with -статации в python. В качестве первого шага я повторно реализовал пример, который генерирует размеченный текст, который появился в ссылке из contextlib.contextmanager (игнорируя обработку исключений на данный момент).

class Markup(object):
    def __init__(self):
        self.tags = []
        self.append = self.tags.append
        self.pop = self.tags.pop

    def tag(self, name):
        self.append(name)
        return self

    def __enter__(self):
        print('<{}>'.format(self.tags[-1]))

    def __exit__(self, exc_type, exc_value, traceback):
        print('</{}>'.format(self.pop()))

>>> m = Markup()
>>> with m.tag('ELEMENT'):
...     print('sample text')
...
<ELEMENT>
sample text
</ELEMENT>

Это работает как ожидалось. Затем я должен подумать, может ли tag() также генерировать пустые элементы:

>>> m = Markup()

# if a function appears as EXPR of "with EXPR: BLOCK", 'ELEMENT' is a container element. .
>>> with m.tag('ELEMENT'):
...     print('sample text')
...
<ELEMENT>
sample text
</ELEMENT> 

# in other cases, ELEMENT is an empty element.
>>> m.tag('ELEMENT')
<ELEMENT/>

Моим наивным глазам кажется вполне реальным, может ли вызываемый абонент определить, вызван ли он из with заявления или нет. Однако я не знаю, возможно ли это обнаружение или нет. Есть ли такой способ и, если есть, то как?

1 Ответ

5 голосов
/ 15 января 2011

Вы на самом деле не звоните tag() "из" оператора with.Вы вызываете tag(), затем передаете возвращаемое значение из tag() в оператор with, который затем вызывает __enter__ для этого переданного значения, затем запускает тело, затем вызывает __exit__.

Так что нет, вы не можете обнаружить оператор with до его фактического вызова (то есть после вызова tag()).

...