Python *args 属性错误

Python *args AttributeError

谁能帮我弄清楚为什么第一个代码有效而第二个无效?:

工作代码

alias = []
alias.append(cx_Oracle.connect('%s/%s@%s' % (username, password, base)))
solve(*alias, **binds)

def solve(*alias, **binds):
    cur = alias[0].cursor()

代码无效

alias = []
alias.append(cx_Oracle.connect('%s/%s@%s' % (username, password, base)))
solve(alias, binds)

def solve(*alias, **binds):
    cur = alias[0].cursor()

错误

AttributeError: 'list' object has no attribute 'cursor'

*** 谢谢大家!这很有帮助!

alias 是传递的所有参数的 tuple。如果您将 list 传递给它,alias 将是包含一个元素 listtuple。相反,您想将 list 解压缩到单独的元素中。然后,alias 将是包含每个元素的 tuple

>>> def a(*arg):
...     print(arg)
...
>>> a([1,2])
([1, 2],)
>>> a(*[1,2])
(1, 2)

**binds 也是如此(如果您正在使用它)- 它不期待字典,它期待来自 字典的 元素,所以如果您已经有了现成的字典,你必须用 **.

以解压形式传递它

问题的发生是因为在第二种情况下,由于在作为参数传递给函数时没有解包列表或字典,它们被传递到 alias 中(在 solve 函数中) alias 的第一个元素是列表 aliasalias 的第二个元素是字典 binds).

显示此内容的示例 -

>>> def a(*nargs, **kwargs):
...     print('nargs : ',nargs)
...     print('kwargs : ',kwargs)
...
>>> x = [1,2,3]
>>> d = {'a':2,'b':4}
>>> a(*x,**d)
nargs :  (1, 2, 3)
kwargs :  {'a': 2, 'b': 4}
>>> a(x,d)
nargs :  ([1, 2, 3], {'a': 2, 'b': 4})
kwargs :  {}

solve 接受任意数量的参数和关键字参数。 *alias 参数是给定普通参数的列表,**binds 是给定关键字参数的列表。

*alias 解包 alias 到参数,例如:

array = [1, 2, 3]
solve(*array) # same as solve(1, 2, 3)

类似地,**bindsbinds 解包为关键字参数。

map = {"a": 1, "b": 2, "c": 3}
solve(**map) # same as solve(a = 1, b = 2, c = 3)

这是工作代码。

solve(*alias, **binds)

如果 alias[1, 2, 3] 并且 binds{"a": 1, "b": 2, "c": 3},那么这个调用等同于

solve(1, 2, 3, a = 1, b = 2, c = 3)

结果如下:

def solve(*alias, **binds):
    # alias is now the argument list
    # [1, 2, 3]
    # bind is now the keyword argument map
    # {"a": 1, "b": 2, "c": 3}
    cur = alias[0].cursor()

这是另一个。

solve(alias, binds)

同样,让我们​​看看如果 alias[1, 2, 3] 并且 binds{"a": 1, "b": 2, "c": 3} 会发生什么。那么这个调用就相当于

solve([1, 2, 3], {"a": 1, "b": 2, "c": 3})

def solve(*alias, **binds):
    # alias is now the argument list 
    # [[1, 2, 3], {"a": 1, "b": 2, "c": 3}]
    # bind is now keyword argument map
    # {}
    cur = alias[0].cursor()

这在 Keyword Arguments **binds, Arbitrary Argument Lists *alias and Unpacking Argument Lists solve(alias, binds)solve(*alias, **binds) 中有描述。

当您调用 solve(alias, binds) 时,参数 aliasbinds 都被赋值给形参 *alias.

这导致 alias[0] 成为列表 [ cx_Oracle.connect('%s/%s@%s' % (username, password, base)) ] 而不仅仅是第一个元素 cx_Oracle.connect('%s/%s@%s' % (username, password, base))。并且列表 [...] 没有属性 'cursor',正如 Python 恰当地抱怨的那样。