开发者

Can I write a function that detect if it is called from 'with'-statement or not?

More specifically, can I detect if a function is called as EXPR in with EXPR: BLOCK statement? I am trying to make myself familiar with the usage of with-statement in python. As a first step, I re-implemented an example, which generate marked up text, appeared in the reference of contextlib.contextmanager (ignoring exception handling for now).

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>

This works as expected. Then, I got to think if tag() can also generate empty elements:

>>> 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/>

To my naive eyes, it seems doable if callee can detect if it is called from with-statement 开发者_如何转开发or not. However, I do not know if this detection is possible or not. Is there such a way and, if there is, how?


You're not actually calling tag() "from" the with statement. You're calling tag(), then passing the return value from tag() to the with statement, which then calls __enter__ on that passed-in value, then runs the body, then calls __exit__.

So no, you can't detect the with statement before it's actually invoked (which is after tag() is called).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜