Why to use __setattr__ in python?

后端 未结 7 1194
隐瞒了意图╮
隐瞒了意图╮ 2020-12-16 11:12

I don\'t know for why using __setattr__ instead simple referencing like x.a=1.

I understand this example:

class Rectangle:         


        
相关标签:
7条回答
  • 2020-12-16 11:34

    The first use of __setattr__ is to be overwritten in a class definition.

    class Foo ( object ) :
    
        def __init__ ( self ) :
            self.x = 'looser'
    
        def __setattr__ ( self, name, value ) :
            if name == 'x' :
                print( 'Hello, {} !'.format( value ) )
                self.x = value
    

    Problem, Foo() will print an infinite sequence of :

    'Hello, looser !'
    

    There comes the second use which is that, when you're doing that, you can call setattr from the parent class (object by default) to avoid infite recursion :

    class Foo ( object ) :
    
        def __setattr__ ( self, name, value ) :
            self.bar( name, value )
            object.__setattr__( self, name, value )
    
        def bar ( self, name, value ) :
            print( 'Setting {} to {}.'.format( name, value ) )
    

    And therefore :

    f = Foo()
    
    >> 'Hello, winner !'
    
    f.x
    
    >> 'winner'
    
    0 讨论(0)
  • 2020-12-16 11:36

    You don't call it yourself. Period. If you need to use a string because you don't know the name beforehand (very bad idea in 99% of all cases where one might think they need this, nearly always a dict or list is a better/saner choice), you use the built-in setattr function.

    However, it is called for you - when you do a.x = ..., that's done as a.__setattr__('x', ...) (this is propably an oversimplification). And some objects overload it to allow some trickery, e.g. to emulate immutability. See the documentation of "special methods".

    0 讨论(0)
  • 2020-12-16 11:36

    I can envision an application where, for example, you override __setattr__ and __getattr__ to provide object-like access to some other data structure that isn't kept in memory. For example, you could create an object where foo.CustomerName = "John" updated the CustomerName column in a database row pointed to by foo to contain the value "John". I.e., foo.__setattr__ would use the attribute name and value to construct a command to update a database on disk. I'd hate to have to write such a thing, but it would be possible.

    0 讨论(0)
  • 2020-12-16 11:37

    the __setattr__ can be used to reflection, where an propperty on the object Rectangle can be created at runtime, there are more about it on http://en.wikipedia.org/wiki/Reflection_%28computer_science%29

    class Rectangle:
        def __init__(self):
            #... code ...
    
    x = Rectangle()
    #x.__setattr__('newProperty',30)      Edited after comment
    setattr(x, 'newProperty', 30)
    print x.newProperty #>>> 30
    
    0 讨论(0)
  • 2020-12-16 11:40
    class Name(object):
        pass
    
    obj=Name()
    
    #just i have created object two way 
    #first
    
    obj.a="first"
    print obj.a
    
    #answer= "first"
    #second
    
    obj.__setattr__('b','second')
    print obj.a
    #answer= "second"
    
    0 讨论(0)
  • 2020-12-16 11:45

    Note that __xxx__ are operator overloading methods of the class and as such should only be used in special situations and not in cases as in your example.

    For example, __setattr__ intercepts all attribute assignments and can be used to change the behaviour of your class when a value is assigned to an attribute.

    0 讨论(0)
提交回复
热议问题