Question

The goal of this question is to understand how "built in" are the built-in functions in python.

If I override setattr method, how can I get it back? For example, I have class "Working" like this:

class WorkingSetAttr:
    def a(self): return 'a'
    def b(self): return 'b'

and class "NonWorking" like this:

class NonWorkingSetAttr: 
    def a(self): return 'a'
    def b(self): return 'b'
    def __setattr__(self,a,b): pass

Now I create objects w and n, and run the following:

w = WorkingSetAttr()
setattr(w,'a',w.b)
print "w.a = %s, w.b = %s" % (w.a(), w.b())

n = NonWorkingSetAttr()
setattr(n, 'a', n.b)
print "n.a = %s, n.b = %s" % (n.a(), n.b())

The output is:

w.a = b, w.b = b
n.a = a, n.b = b

Notice that n.a should print "b", but it prints "a" because setattr does not change the attribute.

The question is: How should I modify the object n so that it works like object w. Notice that I mean objects, not classes.

Was it helpful?

Solution

You can just remove the custom __setattr__ from the class object.

>>> n = NonWorkingSetAttr()
>>> setattr(n, 'a', n.b)
>>> print("n.a = %s, n.b = %s" % (n.a(), n.b()))
n.a = a, n.b = b
>>> 
>>> del NonWorkingSetAttr.__setattr__
>>>
>>> setattr(n, 'a', n.b)
>>> print("n.a = %s, n.b = %s" % (n.a(), n.b()))
n.a = b, n.b = b

Note that this modifies the class, not the object. You (almost certainly) don't want to modify the object itself, because then you have an object that looks like it should be a NonWorkingSetAttr but is in fact some sort of dynamic thingy that you don't really understand.

If you can't modify the class, you can just make a subclass and re-overwrite __setattr__ with object's:

>>> class FixedNonWorkingSetAttr(NonWorkingSetAttr):
...     __setattr__ = object.__setattr__
... 
>>> n = FixedNonWorkingSetAttr()
>>> setattr(n, 'a', n.b)
>>> print("n.a = %s, n.b = %s" % (n.a(), n.b()))
n.a = b, n.b = b
>>> isinstance(n, NonWorkingSetAttr)
True
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top