参数解包和类变量赋值

2024-09-29 19:27:02 发布

您现在位置:Python中文网/ 问答频道 /正文

嗨,我有下面的代码,它试图创建一个类的实例并给它赋值。我尝试使用*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]

我得到一个“元组索引超出范围”错误。正如您从注释行中看到的,我以前使用位置参数来完成这项工作(成功了),并使用了如下行来完成:

^{pr2}$

在这种情况下,使用*args的正确方法是什么?我应该用*夸克吗?在


Tags: 代码selfidinitdefargstestdataprint
3条回答

如果不知道将向函数传递多少个参数,则只应使用*args。在

在您的例子中,看起来您需要所有president, alive, terms, firstelected。拥有一个将所有这些都作为参数的构造函数没有什么错。在

使用*kwargs有几个原因。一种情况是,除非用户希望指定默认值,否则应该使用默认值。在

有关详细信息,请参见this questionthis questionofficial documentation。在


针对您的评论

我建议你为每位总统拥有datedied属性。如果它们还没有死,那么值应该是None。当您只使用功能扩展某些实例时,就很难(但并非不可能)对代码进行推理。在

话虽如此,如果您希望每个总统的任意属性显然不适用于每个实例,那么您可以使用关键字参数。但是添加属性并不局限于构造函数。我只想用 setattr()getattr()。在

如何使用kwargs

设置类属性
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

您正在调用President(testdata),而您应该执行President(*testdata),以便在调用构造函数时解压列表。在

现在,实际上传递的是单个参数(列表),因此IndexError:传递的是单个参数,因此args等于[testdata],而不是{}。在


不过,正如另一个答案中提到的,在这里的构造函数中使用*args并不是很像Python。你知道你期望的论点,所以就用这些。在

不过,在调用函数时使用它是可以的。在

只向President()传递一个参数,即列表

['FDR', False, 4, 1933]

如果要将该列表中的项作为单独的参数传递,请按如下方式执行:

^{pr2}$

正如panicy上校指出的,在您的例子中,参数解包的使用有点毫无意义——假设您的实际用例更复杂,并且证明了它的使用是合理的。在

更新

您的评论实际上是一个后续问题,最好单独提问,但是:

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)

这也展示了如何定义默认值。在

相关问题 更多 >

    热门问题