質問

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.

役に立ちましたか?

解決

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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top