Могу ли я написать функцию, которая обнаруживает, называется ли она из «с» или нет?

StackOverflow https://stackoverflow.com/questions/4698064

  •  11-10-2019
  •  | 
  •  

Вопрос

Более конкретно, могу ли я обнаружить, называется ли функция как 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/>

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

Это было полезно?

Решение

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top