Python使用kwargs初始化对象

3

我正在尝试使用kwargs初始化对象,并使用以下代码:

class A:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
    def __repr__(self):
        return "A('%s', '%s', '%s')" % (self.name, self.age, self.address)


a = A(name="J Smith", age=20, address ="New York")
b = A(name="B Jones", age=40, address = "Chicago")

我目前使用kwargs的方法速度比逐个更新变量(例如a.name="J Smith",a.age=20)要慢得多。另外,在初始化'b'之后,我发现实例'a'的属性已被'b'的属性覆盖。这里是否有什么我做错的地方或者我漏掉了什么步骤?


1
我发现实例'a'的属性已被覆盖为'b'的属性。但这在我的机器上并没有发生。你能否发布一些代码来演示你的问题?目前,你有一些语法错误。 - Kevin
在Python 3.2.2中运行此代码,我既没有看到速度变慢,也没有看到属性被覆盖。您能否复制/粘贴一个显示问题的Python会话? - Matthew Trevor
@CorleyBrigman 这应该不是问题,因为实例属性总是会覆盖类属性。 - Matthew Trevor
http://codepad.org/Q4cIAbUP 运行正常。 - DhruvPathak
谢谢大家,现在看起来这个例子代码似乎可以工作了,这是我问题的简化版本。我以为问题与kwargs有关,所以我没有发布整个类。我会尝试看看能否再次重现错误。再次感谢大家的帮助。 - Lezan
显示剩余3条评论
1个回答

4

您说得对,使用**kwargs更新类的速度几乎比手动设置每个变量慢了一倍。但是,两个单独的类对象互相覆盖不应该有任何问题。参考文献:

import timeit

class A:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

class B:
    def __init__(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

class C:
    def __init__(self, name, age):
        self.name = name
        self.age = age

def initialize_class_a():
    a = A(name="J Smith", age=20)
    b = A(name="B Jones", age=40)
    return a.name, b.name

def initialise_class_b():
    a = B(name="J Smith", age=20)
    b = B(name="B Jones", age=40)
    return a.name, b.name

def initialise_class_c():
    a = C(name="J Smith", age=20)
    b = C(name="B Jones", age=40)
    return a.name, b.name

print(initialize_class_a())
# ('J Smith', 'B Jones')
print(initialise_class_b())
# ('J Smith', 'B Jones')
print(initialise_class_c())
# ('J Smith', 'B Jones')

print(timeit.timeit("initialize_class_a()", "from __main__ import initialize_class_a"))
# 1.93
print(timeit.timeit("initialise_class_b()", "from __main__ import initialise_class_b"))
# 2.19
print(timeit.timeit("initialise_class_c()", "from __main__ import initialise_class_c"))
# 1.03

请注意,在每次运行中,两个独立的类对象a.name和b.name的名称仍然不同。

谢谢,是的它仍然比较慢,但差别不大,并且现在实例是不同的。我只是在代码的其他地方有一个bug,我错误地把它归因于使用kwargs,这段代码和上面的注释帮助澄清了这一点,非常感谢! - Lezan
没问题,很高兴你解决了它!在提到kwargs比较慢之后,我也想亲自验证一下,所以这对我来说是一个很好的学习经验。 - CasualDemon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接