编程语言
首页 > 编程语言> > python – 在体内代码之前调用的上下文管理器出口

python – 在体内代码之前调用的上下文管理器出口

作者:互联网

我一直在玩Python自己的上下文管理器.我看到一些奇怪的行为很可能是由于我的实施.

我看到在’with’上下文中的语句之前调用的__exit__代码.例如,以下是代码段:

with ProgressBar(10) as p:
  p.update(1)

这是例外:

Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
AttributeError: 'NoneType' object has no attribute 'update'

我把调试放在所有的__enter __,__ exit__,并更新了我的上下文管理器的方法.看起来在update()之前调用__exit__.这没有任何意义所以我必须错过一些简单的东西.

这是我的简单上下文管理器类:

class ProgressBar(object):
    """Progress bar that normalizes progress to [0 - 100] scale"""

    def __init__(self, max_value):
        """Create progress bar with max_value"""

        self._current_value = 0.0
        self._completed_value = 100.0
        self._max_value = float(max_value)
        print 'init', max_value

    def __enter__(self):
        """Start of context manager, 'with' statement"""

        print 'enter'
        self._current_value = 0.0

    def __exit__(self, exc_type, exc_value, traceback):
        """Start of context manager, 'with' statement"""

        print 'exit'
        self._current_value = self._completed_value

        # Not handling any exceptions, so they'll be raised automatically
        # To ignore exceptions return True or inspect arguments to handle

        return False

    def update(self, value):
        """Update progress value"""

        print 'update'
        if value >= self._max_value:
            self._current_value = 100
        else:
            self._current_value = (value / self._max_value) * self._completed_value

        print '\r%s' % (self._current_value),

解决方法:

从文档:

object.__enter__(self)

Enter the runtime context related to this object. The with statement
will bind this method’s return value to the target(s) specified in
the as clause of the statement, if any.

你没有从__enter__返回任何东西(因此你一如既往地返回None).如果你回归自我,你会得到

init 10
enter
update
10.0 exit

标签:python,contextmanager
来源: https://codeday.me/bug/20190716/1480277.html