我可以编写一个函数来检测是否从'with'语句中调用它?

时间:2011-01-15 04:54:24

标签: python with-statement

更具体地说,我可以在EXPR语句中检测函数是否被调用为with EXPR: BLOCK吗? 我想让自己熟悉python中with - 语句的用法。作为第一步,我重新实现了一个生成标记文本的示例,它出现在contextlib.contextmanager的{​​{3}}中(暂时忽略了异常处理)。

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 个答案:

答案 0 :(得分:5)

您实际上并未从“tag()声明中调用with”。您正在调用tag(),然后将返回值从tag()传递给with语句,然后在该传入值上调用__enter__,然后运行正文,然后拨打__exit__

所以不,你在with语句被实际调用之前(在调用tag()之后)就无法检测到它。