Bar*_*cki 5 python arguments function cookbook python-2.7
我在Python Cookbooks中阅读了一个解决方案,用于创建仅允许名称参数的函数.我编写了自己的代码来试试:
class Reporter(object):
def __init__(self, *, testline=None, sw_ver= None, directory=None):
pass
if __name__ == "__main__"
r = Reporter()
Run Code Online (Sandbox Code Playgroud)
但是解释器显示此错误:
File "Reporter.py", line 6
def __init__(self, *, testline=None, sw_ver= None, directory=None):
^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)
为什么会显示这个?
您使用的代码是有效的语法,但对于python3,所以本书必须使用python3语法,它只允许关键字参数,pep-3102:
您还可以在参数列表中使用bare*来表示您不接受可变长度参数列表,但是您确实只有关键字参数.
使用您的代码并在python 3中传递非关键字会出错,但原因不同:
TypeError Traceback (most recent call last)
<ipython-input-2-b4df44fa1e0c> in <module>()
1 if __name__ == "__main__":
----> 2 r = Reporter(4)
3
TypeError: __init__() takes 1 positional argument but 2 were given
Run Code Online (Sandbox Code Playgroud)
使用关键字后,它可以正常工作:
In [4]: if __name__ == "__main__":
r = Reporter(testline=4)
...:
Run Code Online (Sandbox Code Playgroud)
使用具有相同语法的函数可能会产生更明显的错误:
def f(*, foo=None, bar=None):
return foo, bar
In [6]: f(4)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-6-a122d87dbe99> in <module>()
----> 1 f(4)
TypeError: f() takes 0 positional arguments but 1 was given
Run Code Online (Sandbox Code Playgroud)
如果你想允许一些位置args并且传递了可选的关键字args但是只有名字,那么它也很有用:
def f(a,b, *, foo=None, bar=None):
return a, b, foo, bar
Run Code Online (Sandbox Code Playgroud)
然后通过3位置args将出错:
In [8]: f(1,2,3)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-b61741968103> in <module>()
----> 1 f(1,2,3)
TypeError: f() takes 2 positional arguments but 3 were given
Run Code Online (Sandbox Code Playgroud)
我最近收到了关于这个答案的评论.
→请注意它的目标是python2,因为OP用python2.7明确地标记了他的问题.对于python3,请参阅Padraic Cunningham的回答.
[原始答案]
你可能不会*单独使用它.在函数声明中,它表示"解压缩此变量中的任何其他未命名参数",因此您必须为其指定变量名称.
您可以通过给它命名来实现您想要的,然后检查它是否为空,如下所示:
class Reporter(object):
def __init__(self, *args):
assert not args, "Reporter.__ini__ only accepts named arguments"
Run Code Online (Sandbox Code Playgroud)
然后你想要添加你可以允许的参数,如下所示:
# won't work
def __init__(self, *args, testline=None, sw_ver= None, directory=None):
Run Code Online (Sandbox Code Playgroud)
......除了*args需要在最后.但是如果你把它们放在最后,你会发现你仍然可以先传递未命名的其他参数.
你必须扭转逻辑,只采取kwargs.
class Reporter(object):
def __init__(self, **kwargs):
testline = kwargs.pop('testline', None)
sw_ver = kwargs.pop('sw_ver', None)
directory = kwargs.pop('directory', None)
assert not kwargs, 'Unknown arguments: %r' % kwargs
Run Code Online (Sandbox Code Playgroud)
现在,如果有人试图提供未命名的辩论,他们将被拒绝.
星号运算符 ( *) 用于解包。您不能将其用作参数。
您可能想阅读可变长度参数元组:
\n\n\n\n\n函数可以采用可变数量的参数。以 * 开头的参数名称\n 将参数收集到一个元组中。例如,\n printall 接受任意数量的参数并打印它们:
\n
def printall(*args):\n print args\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\nGather 参数可以具有任何您喜欢的名称,但 args 是常规名称。这里\xe2\x80\x99是该函数的工作原理:
\n
>>> printall(1, 2.0, \'3\') (1, 2.0, \'3\')\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1878 次 |
| 最近记录: |