如何使用Python装饰器处理’self’参数

我正在尝试设置一些装饰器,以便我可以执行以下操作:

class Ball(object):
    def __init__(self, owner):
        self.owner = owner

class Example(CommandSource):
    @command
    @when(lambda self, ball: ball.owner == self) 
    def throwBall(self, ball):
        # code to throw the ball
        pass

e = Example()
ball = Ball(e)
commands = e.listCommands(ball)  # commands = [ 'throwBall' ]

这当前不起作用,因为当调用验证lambda时,没有传递自身参数.

现在这样的事情很好:

class Example(CommandSource):
    @command
    @when(lambda ball: ball.is_round) 
    def throwBall(self, ball):
        pass

但这也行不通:

class Example(CommandSource):
    def verify_owner(self, ball):
        return ball.owner == self

    @command
    @when(verify_owner) 
    def throwBall(self, ball):
        pass

目的是能够将类中的方法标记为“命令”,并获取有效运行的命令列表.实际上运行该方法没有改变.我想在这里使用装饰器,因为它似乎是最不笨的方式来做到这一点.实际上我正在尝试使用Python设置一个小DSL.

但我遇到了困难,尤其是自我论证.这是我当前执行的命令,when和CommandSource:

def command(cmd):
    if getattr(cmd, 'command', False): return cmd

    def wrapper(*args, **kwargs):
        return cmd(*args, **kwargs)

    wrapper.validators = []
    wrapper.command = True

    return wrapper

def when(predicate):
    def createCommand(cmd):    
        newcmd = command(cmd)
        newcmd.validators.append(predicate)
        return newcmd
    return createCommand

class CommandSource(object):
    def listCommands(self, *args, **kwargs):
        commands = []
        for command in dir(self.__class__):
            func = getattr(self, command, None)

            if func == None or getattr(func, 'command', False) == False:
                continue
            valid = True
            for validator in func.validators:
                if not validator(*args, **kwargs):
                    valid = False
                    break
            if valid:
                commands.append(command)
        return commands

解决方法:

更改您的CommandSource如下:

class CommandSource(object):

    def listCommands(self, *args, **kwargs):
        commands = []
        for command in dir(self.__class__):
            func = getattr(self, command, None)
            if func == None or getattr(func, 'command', False) == False:
                continue
            for validator in func.validators:
                if not validator(self, *args, **kwargs):
                    break
            else:
                commands.append(command)
        return commands

并使用您的第一个代码.

上一篇:python – 将声明性DSL转换为嵌套函数调用


下一篇:Ubuntu中使用dnw工具:没有找到/dev/secbulk0