用逗号表示奇怪的语法

问题描述 投票:1回答:2

我正在学习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, ['*']

谁能解释一下?

python
2个回答
1
投票

在这种情况下,状态不是直接装饰器,而是元装饰器或装饰器生成函数:它不直接应用于函数,而是应用于其他一些参数,它将用于返回“真实的“装饰者:

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)
  1. 将函数保存到func
  2. 将参数设置为默认值和
  3. 将“真正的”装饰器应用于该功能,

这实际上意味着@state和@state()现在完全一样。

在我看来,检查应该是一个断言,所以你可以快速找到并修复你的代码中的这种不一致,但是谁写的那个决定只是默默地忽略它们。


1
投票

另外,我不知道以下行是做什么的:

func, allowed = allowed, ['*']

这是一种略短的写作方式

func = allowed
allowed = ['*']

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

© www.soinside.com 2019 - 2024. All rights reserved.