Roman Kiselev
Roman Kiselev

Reputation: 1174

Why each new property, dynamically added to an existing class, overwrites previously added ones?

I am creating a Python class with a very long list of properties. To avoid boilerplate, I want to define a minimalistic class, and then extend it with my custom properties, which names are provided as a list. However, when I create and add individual properties in a loop, all of them turn out to be identical. What am I missing?

class C(object):
    def _get_item(self, name):
        print(f"I'm getter of {name}")
    def _set_item(self, name, value):
        print(f"I'm setter of {name}")


for item in ['x', 'y', 'z']:
    prop = property(fget = lambda self: self._get_item(item),
                    fset = lambda self, x: self._set_item(item, x))
    setattr(C, item, prop)

o = C()
print(C.x == C.z)   # False
print(C.x is C.z)   # False
o.z                 # I'm getter of z  -  ok
o.y                 # I'm getter of z  -  ??
o.x                 # I'm getter of z  -  ??
o.x = 3             # I'm setter of z  -  ??
o.z = 5             # I'm setter of z  -  ok

Why does the implementation of each property get overridden every time I add a new property? And yet C.x == C.z results in False?

My hypothesis was that they share the same memory, so if I explicitly create a deep copy, I should solve this puzzle. I imported copy and modified line 11 of the script above. However, the output is still the same!

import copy

    ...
# making a deepcopy of the new property
    setattr(C, item, copy.deepcopy(prop))

Upvotes: 1

Views: 15

Answers (0)

Related Questions