您好我有以下代码,它尝试创建一个类的实例并为其分配参数值。我正在尝试使用* args执行此操作,如下所示:
def main():
testdata = ['FDR', False, 4, 1933]
apresident = President(testdata)
print apresident
print apresident.alive
class President:
id_iter = itertools.count(1)
#def __init__(self, president, alive, terms, firstelected):
def __init__(self, *args):
self.id = self.id_iter.next()
self.president = args[0]
self.alive = args[1]
self.terms = args[2]
self.firstelected = args[3]
我收到“元组索引超出范围”错误。从注释行中可以看出,我以前使用位置参数来完成这个(有效),并使用如下行来执行此操作:
self.president = president
在这种情况下使用* args的正确方法是什么?我应该使用* kwargs吗?
答案 0 :(得分:3)
您只将一个参数传递给President()
,即列表
['FDR', False, 4, 1933]
如果要将该列表中的项目作为单独的参数传递,请按以下方式执行:
apresident = President(*testdata) # note the * character
正如Panic上校指出的那样,在你的例子中,使用参数解包有点毫无意义 - 可能是你的实际用例更复杂,并且证明了它的使用是合理的。
<强>更新强>:
你的评论确实是一个后续问题,作为一个单独的问题会更好,但是:
def main():
testdata = {
"president": "FDR",
"alive": False,
"terms": 4,
"firstelected": 1933,
}
apresident = President(**testdata)
anotherpresident = President(president="BHO", terms=2, firstelected=2008)
print apresident
print apresident.alive
print anotherpresident
print anotherpresident.alive
class President:
id_iter = itertools.count(1)
#def __init__(self, president, alive, terms, firstelected):
def __init__(self, **kwargs):
self.id = self.id_iter.next()
self.president = kwargs.get("president", None)
self.alive = kwargs.get("alive", True)
self.terms = kwargs.get("president", 1)
self.firstelected = kwargs.get("president", None)
这显示了如何定义默认值。
答案 1 :(得分:2)
如果你不知道将多少个参数传递给函数,你应该只使用*args
。
在您的情况下,您似乎需要全部president, alive, terms, firstelected
。拥有一个将所有这些作为参数的构造函数没有任何问题。
*kwargs
有几个原因。一种是如果你有默认值应该使用,除非用户想要指定它们。
有关详细信息,请参阅this question,this question和official documentation。
我建议你做为每位总统提供datedied
财产。如果他们尚未死亡,则该值应为None
。当您仅使用功能扩展某些实例时,对代码进行推理变得更加困难(但并非不可能)。
话虽如此,如果你想要每个总统的任意属性显然不适用于每个实例,那么你可以使用关键字参数。但添加属性不仅限于构造函数。我会简单地使用 setattr()和getattr()。
class President(object):
def __init__(self, *args, **kwargs):
for name, value in kwargs.items():
# Make each keyword-argument a property of the class.
setattr(self, name, value)
tVar = President(is_cool=True)
print tVar.is_cool # Returns True
答案 2 :(得分:1)
您正在调用President(testdata)
,当您应该执行President(*testdata)
时,为了在调用构造函数时解压缩列表。
现在,你基本上传递了一个参数(列表),因此IndexError
:你传递了一个参数,所以args
等于[testdata]
并且不是testdata
。
正如在另一个答案中所提到的,在你的构造函数中使用*args
并不是非常Pythonic。你知道你期望哪些参数,所以只需使用它们。
但是,当你调用这个函数时,可以使用它。