【问题标题】:Check condition before method call在方法调用之前检查条件
【发布时间】:2012-06-09 21:31:05
【问题描述】:

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

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

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

    @started
    def doServerAction(self):
       ...

【问题讨论】:

  • 你试过把装饰器直接放在课堂上吗?我在装饰器上的工作还不够多,不知道这会有多好,但这是我开始寻找的地方
  • 正如post所说,如果是python2.6或更高版本,你的装饰器有办法访问类变量
  • @inspectorG4dget 是的,装饰器在类中。
  • @xvatar 看起来可能很接近,但我仍然不确定如何访问方法装饰器中的类变量。

标签: python


【解决方案1】:

记住装饰器是什么

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

完全等同于:

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

装饰器是在函数上调用的,所以调用第一个参数self是没有意义的。此外,装饰器在定义时在函数上调用,并且它返回的任何内容都用于代替函数。因此,即使您的started 装饰器没有通过尝试访问函数的_started 属性来抛出AttributeError,它也会返回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 函数,这使得修饰函数“看起来更像”原始函数。

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

【讨论】:

  • 这正是我想要的。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多