有没有办法在类的方法中定义强制* args(任意参数)?
class foo():
def __init__(self,*args):
....
鉴于此,你可以从foo-class创建一个对象而不需要任何参数x = foo(),即它是可选的。任何想法如何将其改为非可选或“给我至少一个参数” - 一切?
另一个问题涉及使用x = foo(* list)解压缩列表 - >有没有办法将列表识别为列表并自动解压缩列表,这样您就不必在函数/方法调用中使用*?
THX
答案 0 :(得分:4)
*args
旨在接收正常参数已经 的所有参数。
通常,如果您需要一个必需的参数,您只需使用一个普通的参数:
>>> def foo(arg, *rest):
... print arg, rest
...
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes at least 1 argument (0 given)
如果你认为在元组中收集所有参数更为优雅,你必须自己处理错误情况:
>>> def foo(*args):
... if len(args) < 1:
... raise TypeError('foo() takes at least 1 argument (%i given)' % len(args))
...
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in foo
TypeError: foo() takes at least 1 argument (0 given)
但是你可以(或者应该)看到,从该函数的签名中可以看出,对于使用该函数的任何人来说,该函数有多少参数是强制性的。你应该完全避免这种情况,或至少记录下来。
还有其他问题:如果你给foo()
的参数赋予可迭代的参数(比如字符串),你就不会得到预期的结果。
回复下面的评论,您的第一种方法是正确的:列出一个列表。
def scrape(urls):
for url in urls:
do_something(url)
调用者只需传递一个只包含一个元素的列表:scrape(['localhost'])
。
更好的方法可能是只使用一个URL并让调用者遍历列表。在这种情况下,如果她想要,调用者可以并行操作。
关于你的第二个问题 1 :要么你的函数将列表作为参数,要么不是。在你的程序中传递列表是否有意义,或者它没有。
我想,我不完全确定你在那里问什么,但是你的整个问题听起来像你找到了一个闪亮的新工具,现在你想在任何地方使用它,无论它是否有意义。
1 请不要一次提出多个问题!
答案 1 :(得分:2)
测试结果元组的长度,或者在它之前加上一个或多个普通参数。
没有
答案 2 :(得分:0)
对于“至少给我一个参数”,只需检查你收到的元组的len()
,如果你没有得到至少一个则抛出异常。在这里,我使用的事实是空元组是“虚假的”来隐含地这样做:
def __init__(self, *args):
if not args:
raise TypeError("__init__ takes at least 2 arguments (1 given)")
对于“自动拆包”,您还需要对此进行测试并自行执行。一种方法可能是:
if len(args) == 1 and not isinstance(args[0], basestring) and iter(args[0]):
args = args[0]
iter()
将始终为真,但如果您传递的内容不可迭代,则会引发异常。如果您想提供更友好的错误消息,您可以抓住它并提出其他内容。
另一种方法是编写你的方法,以便递归迭代args
的所有元素及其中的所有子容器;那没关系。
或者,你知道,只需让调用者在迭代中传递,并且不要混淆*args
。如果调用者想要传入单个项目,则可以使用简单的语法将其转换为列表:foo([item])