我将尝试设置一些装饰器,以便我可以做如下操作:
但这个也不起作用:
意图是能够将类中的方法标记为“命令”,并获取可运行的命令列表。实际运行方法不变。我想在这里使用装饰器,因为它似乎是最简单的方法来做到这一点。实际上,我正在尝试使用Python设置一个小型DSL。
但我遇到了困难,特别是对于self参数。这是我的command、when和CommandSource的当前实现:
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时,没有传递self参数。
现在像这样的东西可以正常工作:
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。
但我遇到了困难,特别是对于self参数。这是我的command、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
for
循环中使用else
。 - Joseph Kingry