我正在学习python。我刚刚完成了关于装饰器的教程。我去找了一些代码中的装饰器,但是看到了更多奇怪和不熟悉的东西。
def state(allowed=['*']):
def decorator(func):
func.__fsm_state__ = True
func.__fsm_allowed__ = allowed
return func
if callable(allowed):
func, allowed = allowed, ['*']
return decorator(func)
return decorator
我不知道以下行是做什么的:
func, allowed = allowed, ['*']
谁能解释一下?
在这种情况下,状态不是直接装饰器,而是元装饰器或装饰器生成函数:它不直接应用于函数,而是应用于其他一些参数,它将用于返回“真实的“装饰者:
def a(myargs): # applied to some arguments
def b(func): # decorator
do_smth(func, myargs)
return b # calling a will return the decorator
@a("world")
def hello(): # do_smth(hello, "world") is called
pass
当你输入
@state(["something"])
def foo():
pass
这将使用[“something”]作为参数调用state函数,该函数将返回装饰器函数,该函数最终应用于函数foo,设置__fsm_state__
和__fsm_allowed__
属性,具体取决于最初传递给@state的参数。
当你改用
@state()
def foo():
pass
允许(反过来,__fsm_allowed__
)将被设置为["*"]
的默认值,您可以在状态函数的声明中看到它。
如果你错过括号,那就是Buf
@state # <- no () there
def foo():
pass
函数foo被认为是状态的参数(所以allowed
现在是foo而不是它实际上应该是的那个列表),这可能会导致细微的错误 - 这就是为什么在状态的定义中,有检查
if callable(allowed):
它捕获了直接传递foo的错误,并假设你的意思是默认参数(allowed=["*"]
)
以下代码,
func, allowed = allowed, ['*']
return decorator(func)
这可以略微简化为
func = allowed
allowed = ["*"]
return decorator(func)
这实际上意味着@state和@state()现在完全一样。
在我看来,检查应该是一个断言,所以你可以快速找到并修复你的代码中的这种不一致,但是谁写的那个决定只是默默地忽略它们。
另外,我不知道以下行是做什么的:
func, allowed = allowed, ['*']
这是一种略短的写作方式
func = allowed
allowed = ['*']
搜索“元组分配”以获取更多信息。