上下文管理器定义出错

时间:2016-11-10 23:09:29

标签: python contextmanager

我有以下Python脚本:

*.hs

当我尝试运行脚本时,我得到以下内容:

from contextlib import contextmanager

@contextmanager
def my_content_manager():
    self.entrance = True

    try:
        yield
    except Exception as ex:
        self.entrance = False

with my_content_manager() as cm:
    print (cm.entrance)

print (cm.entrance)

为什么?我该如何解决这个错误?

感谢。

2 个答案:

答案 0 :(得分:3)

一般来说,使用课程可能是一种更好的方法(正如另一个答案所示)。但是,我记得函数对象可以有属性。我遇到了this相关的问题,这导致了以下技巧(看起来似乎滥用了该功能):

from contextlib import contextmanager

@contextmanager
def my_content_manager():
    my_content_manager.entrance = True
    try:
        yield my_content_manager.entrance
    finally:
        my_content_manager.entrance = False
my_content_manager.entrance = False

with my_content_manager() as cm:
    print(my_content_manager.entrance)
    # Or, print(cm)

print(my_content_manager.entrance)

这种技术可能存在缺陷。我只是将其作为好奇心发布。

答案 1 :(得分:1)

错误NameError: name 'self' is not defined非常明显,没有双关语意。 self只是类在方法中使用的名称。您还没有在任何地方定义self,因此Python不知道该怎么做。此外,您已经定义了一个函数,而不是一个类中的方法,所以这并不接近于工作。使用类来定义上下文管理器,如下所示:

class MyContextManager(object):
    def __init__(self):
        self.entrance = True

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_val:
            self.entrance = False
        # signal that the exception was handled and the program should continue
        return True


with MyContextManager() as cm:
    print (cm.entrance)
    raise Exception()

print (cm.entrance)

编辑:如果,根据评论中的要求,您只想打印一个值而不是将其存储在某个地方:

@contextmanager
def my_content_manager():
    try:
        yield
    except Exception as ex:
        print(False)
    else:
        print(True)