我可以编写一个函数来检测它是否是从“with”语句调用的吗?

发布于 2024-10-11 20:00:41 字数 1377 浏览 6 评论 0原文

更具体地说,我可以检测函数是否在 with EXPR: BLOCK 语句中被调用为 EXPR 吗? 我试图让自己熟悉 python 中 with 语句的用法。作为第一步,我重新实现了一个示例,该示例生成标记文本,出现在 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 语句调用的,这似乎是可行的或不。但是,我不知道这种检测是否可能。有没有这样的方法,如果有的话,如何实现?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏日浅笑〃 2024-10-18 20:00:41

您实际上并没有从 with 语句“调用”tag()。您正在调用 tag(),然后将 tag() 的返回值传递到 with 语句,该语句随后调用 __enter__ 传入的值,然后运行正文,然后调用 __exit__。

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

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文