Question

I am trying to initialise objects using kwargs and am using the code below:

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")

My current problem with this method is that it seems to be much slower using kwargs instead of updating the variables individually (i.e a.name="J Smith", a.age=20) instead of passing them as dictionaries. Also after I initialise 'b', I find out that the attributes of instance 'a' have been overwritten with the attributes of 'b'. Is there something I am doing wrong here and/or is there a step that I am missing?

Was it helpful?

Solution

You are correct that using **kwargs to update the class is almost twice as slow compared to manually setting each variable. However there should be no issues with two separate class objects overwriting one another. Reference:

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

Notice that in each run the name of the two separate class objects, a.name and b.name, are still reporting to be different.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top