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
将是包含一个元素 list
的 tuple
。相反,您想将 list
解压缩到单独的元素中。然后,alias
将是包含每个元素的 tuple
。
>>> def a(*arg):
... print(arg)
...
>>> a([1,2])
([1, 2],)
>>> a(*[1,2])
(1, 2)
**binds
也是如此(如果您正在使用它)- 它不期待字典,它期待来自 字典的 元素,所以如果您已经有了现成的字典,你必须用 **
.
以解压形式传递它
问题的发生是因为在第二种情况下,由于在作为参数传递给函数时没有解包列表或字典,它们被传递到 alias
中(在 solve 函数中) alias
的第一个元素是列表 alias
,alias
的第二个元素是字典 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)
类似地,**binds
将 binds
解包为关键字参数。
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)
时,参数 alias
和 binds
都被赋值给形参 *alias
.
这导致 alias[0]
成为列表 [ cx_Oracle.connect('%s/%s@%s' % (username, password, base)) ]
而不仅仅是第一个元素 cx_Oracle.connect('%s/%s@%s' % (username, password, base))
。并且列表 [...]
没有属性 'cursor',正如 Python 恰当地抱怨的那样。
谁能帮我弄清楚为什么第一个代码有效而第二个无效?:
工作代码
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
将是包含一个元素 list
的 tuple
。相反,您想将 list
解压缩到单独的元素中。然后,alias
将是包含每个元素的 tuple
。
>>> def a(*arg):
... print(arg)
...
>>> a([1,2])
([1, 2],)
>>> a(*[1,2])
(1, 2)
**binds
也是如此(如果您正在使用它)- 它不期待字典,它期待来自 字典的 元素,所以如果您已经有了现成的字典,你必须用 **
.
问题的发生是因为在第二种情况下,由于在作为参数传递给函数时没有解包列表或字典,它们被传递到 alias
中(在 solve 函数中) alias
的第一个元素是列表 alias
,alias
的第二个元素是字典 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)
类似地,**binds
将 binds
解包为关键字参数。
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)
时,参数 alias
和 binds
都被赋值给形参 *alias
.
这导致 alias[0]
成为列表 [ cx_Oracle.connect('%s/%s@%s' % (username, password, base)) ]
而不仅仅是第一个元素 cx_Oracle.connect('%s/%s@%s' % (username, password, base))
。并且列表 [...]
没有属性 'cursor',正如 Python 恰当地抱怨的那样。