6

我有一个名为 Server 的类,它可以启动和停止。除非启动服务器,否则不应调用某些方法,在这种情况下应引发 NotConnectedException。有没有办法在类中的每个方法之前调用一个方法并确定类变量 _started 是否设置为 True?

我尝试使用装饰器,但装饰器函数无法访问类变量。我试图做这样的事情:

class Server(object):
    _started = False
    def started(self):
        if(self._started == False):
            raise NotConnectedException

    @started
    def doServerAction(self):
       ...
4

1 回答 1

9

记住装饰器什么:

@decorate
def foo(...):
    ...

完全等同于:

def foo(...):
    ...
foo = decorate(foo)

装饰器是在function上调用的,所以调用第一个参数self是没有意义的。此外,装饰器在定义时在函数上调用,并且使用它返回的任何内容来代替函数。因此,即使您的started装饰器没有AttributeError通过尝试访问_started函数的属性来抛出 an ,它也会返回None,使您的所有方法都设置为None,因此甚至无法调用。

你想要的是这样的:

import functools

def started(func):
    @functools.wraps(func)
    def wrapper(self, *args, **kwargs):
        if not self._started:
            raise ...
        else:
            return func(self, *args, **kwargs)
    return wrapper

几乎所有的装饰器都是这种形式;他们接受一个函数,创建一个包装器来“围绕”接收到的函数,然后返回包装器。functools.wraps如果您最终在交互式解释器会话中使用此代码,则使用此处很方便;它使用原始函数的名称和文档字符串自动更新wrapper函数,这使得修饰函数“看起来”更像原始函数。

这是否在类内部定义是无关紧要的。

于 2012-06-05T21:41:07.627 回答