是否有办法在类的方法中定义强制性*args(任意参数)?
class foo():
def __init__(self,*args):
....
给定这个,你可以从foo-类创建一个对象而不需要任何参数x=foo(),也就是说它是可选的。有任何想法如何将其更改为非可选或"给我至少一个参数"的东西吗?
另一个问题是关于用x=foo(*list) -->解包列表是否有一种方法可以识别列表为列表并自动解包列表,这样你就不必在函数/方法调用中使用*了?
Thx
*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请不要一次问多个问题!
测试结果元组的长度,或者在其前面放置一个或多个正常参数。
号对于"give me at least one argument ",只需检查收到的元组的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])