Today when I checked some code at the office, I found the following code. It shocked me.
class XXXX():
def __init__(self, k, v):
for i in range(len(k)):
setattr(self, k[i], v[i])
Then I found that most of the classes are written in the same way. That means all the classes are the same class,the only different is their name.
In this project setattr()
is used to set attributes and getattr()
is used to get attributes In profile log setattr
was called 2700 times and getattr
was called 3800 times. The time consume was 0.003sec and 0.005sec respectively (whole process: 0.069sec).
Though I do think setattr
and getattr
drag down the speed, I'm not sure if a rewrite of all the code would make it better.
Does obj.attribute = value run faster than setattr(obj,'attribute',value)
?
Yes, compared to the direct conventional method of accessing an attribute of a given object, the performance of getattr() is slower.
Python setattr() and getattr() goes hand-in-hand. As we have already seen what getattr() does; The setattr() function is used to assign a new value to an object/instance attribute.
Python setattr() function is used to assign a new value to the attribute of an object/instance. Setattr in python sets a new specified value argument to the specified attribute name of a class/function's defined object.
Python setattr() function is used to set a value to the object's attribute. It takes three arguments an object, a string, and an arbitrary value, and returns none. It is helpful when we want to add a new attribute to an object and set a value to it.
Yes, getattr
and setattr
are much slower, at least at the CPU level.
Since __init__
is only called once per object I wouldn't worry about that unless you are creating many, many objects.
If the objects' attributes are accessed many times it could be worth it to rewrite those sections. You should do some careful profiling first, though.
I did a small test. It was roughly 2x slower.
Increment using member took 2.8221039772
Increment using attr took 5.94811701775
Here is my code
import timeit
class Dummy(object):
__slots__ = ['testVal']
def __init__(self):
self.testVal = 0
def increment_using_attr(self):
i = getattr(self, 'testVal')
setattr(self, 'testVal', i+1)
def increment(self):
self.testVal += 1
if __name__ == '__main__':
d = Dummy()
print "Increment using member took {0}".format(timeit.Timer(d.increment).timeit(10000000))
print "Increment using attr took {0}".format(timeit.Timer(d.increment_using_attr).timeit(10000000))
Run on machine Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With