我試圖建立一些裝飾,這樣我可以這樣做「自我」的說法:如何處理與Python裝飾
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' ]
目前這是不行的,因爲當驗證拉姆達被調用時,沒有通過自我論證。
現在是這樣的正常工作:
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
大,這樣的作品,也感謝您使用了'else'的內部'for'循環。 – 2010-03-30 16:59:45