Python强制任意参数列表*args



是否有办法在类的方法中定义强制性*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])

相关内容

  • 没有找到相关文章

最新更新