逗号奇怪的语法

时间:2019-04-10 22:37:37

标签: python

我正在学习python。我刚刚完成了关于装饰器的教程。我去找了一些代码中的装饰器,但是看到了更多奇怪和不熟悉的东西。

end()

我不知道下面的行是什么

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

有人可以解释吗?

2 个答案:

答案 0 :(得分:1)

  

此外,我不知道以下行的作用:

     

func, allowed = allowed, ['*']

这是一种较短的书写方式

func = allowed
allowed = ['*']

搜索“元组分配”以获取更多信息。

答案 1 :(得分:1)

在这种情况下,

状态不是直接的修饰符,而是 meta-decorator 或修饰符生成函数:它不是直接应用于函数,而是应用于其他函数参数,它将用于返回“真实”装饰器:

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”]作为参数来调用状态函数,这将依次返回装饰器函数,该装饰器函数最终将应用于函数foo,设置__fsm_state____fsm_allowed__属性,具体取决于最初传递给@state的参数。

当您改用

@state()
def foo():
    pass

允许的值(依次为__fsm_allowed__)将被设置为默认值["*"],您可以在状态函数的声明中看到它。

如果你错过了方括号,就是

@state  # <- no () there
def foo():
   pass

函数foo被视为要声明的参数(因此allowed现在是foo而不是它实际应有的列表),这可能会导致细微的错误-这就是为什么在state的定义中,有支票

if callable(allowed):

发现直接传递foo的错误,只是假设您的意思是默认参数(allowed=["*"]

以下代码,

func, allowed = allowed, ['*'] 
return decorator(func)

可以稍微简化为

func = allowed
allowed = ["*"]
return decorator(func)
  1. 将函数保存到函数中
  2. 将参数设置为默认值,
  3. 将“真实”修饰符应用于该函数,

这实际上意味着@state和@state()现在可以做完全相同的事情。

我认为,检查应该是断言,因此您可以快速找到并修复代码中的此类不一致之处,但无论写谁的人都决定只是默默地忽略它们。