¿Por qué usar __setattr__ en python?

No sé por qué usar __setattr__ lugar de referencias simples como xa=1 .

Entiendo este ejemplo:

 class Rectangle: def __init__(self): self.width = 0 self.height = 0 x=Rectangle() x.width=20 x.__setattr__('height',30) setattr(x,'width',99) 

pero no entienda por qué usar el código dependiendo de la cadena (‘altura’).

¿Podría explicarme cuáles son las ventajas de __setattr__ ?

Tú no lo llamas tú mismo. Período. Si necesita usar una cadena porque no conoce el nombre de antemano ( muy mala idea en el 99% de todos los casos en que uno podría pensar que lo necesitan, casi siempre un dict o lista es una opción mejor / más sensata), utilice La función setattr incorporada.

Sin embargo, se llama para ti: cuando haces ax = ... , eso se hace como a.__setattr__('x', ...) (esto probablemente sea una simplificación excesiva). Y algunos objetos lo sobrecargan para permitir algunos trucos, por ejemplo, para emular la inmutabilidad. Consulte la documentación de “métodos especiales”.

__setattr__ es un método de clase que se llama mediante el método incorporado setattr . Es decir, si __setattr__ se define en la clase dada. La mayoría de las veces no declara su propia versión de __setattr__ así que asumo que está preguntando qué uso tiene el método setattr .

Supongamos que tiene una var con el nombre del atributo que desea establecer en lugar de simplemente saber el nombre:

 class A(object): def doSth(self, name, val): setattr(self, name, val) 

imposible de hacer con self.name = val

Además, un uso común es con la palabra args:

 class A(object): def __init__(self, *args, **kwargs): for k,v in kwargs.items(): setattr(self, k, v) 

Puedo imaginar una aplicación en la que, por ejemplo, sustituyas a __setattr__ y __getattr__ para proporcionar un acceso similar a un objeto a alguna otra estructura de datos que no esté guardada en la memoria. Por ejemplo, puede crear un objeto donde foo.CustomerName = "John" actualice la columna CustomerName en una fila de la base de datos a la que apunta foo para que contenga el valor "John" . Es decir, foo.__setattr__ usaría el nombre y el valor del atributo para construir un comando para actualizar una base de datos en el disco. Odiaría tener que escribir una cosa así, pero sería posible.

Tenga en cuenta que __xxx__ son los métodos de sobrecarga de operadores de la clase y, como tales, solo deben usarse en situaciones especiales y no en los casos como en su ejemplo.

Por ejemplo, __setattr__ intercepta todas las asignaciones de atributos y puede usarse para cambiar el comportamiento de su clase cuando se asigna un valor a un atributo.

el __setattr__ se puede usar para la reflexión, donde se puede crear una propiedad en el objeto Rectangle en tiempo de ejecución, hay más información al respecto en 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 

El primer uso de __setattr__ se debe sobrescribir en una definición de clase.

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

Problema, Foo() imprimirá una secuencia infinita de:

 'Hello, looser !' 

Ahí viene el segundo uso, que es que, cuando estás haciendo eso, puedes llamar a setattr desde la clase padre ( object por defecto) para evitar una recursión infinita:

 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 ) ) 

Y por lo tanto :

 f = Foo() >> 'Hello, winner !' fx >> 'winner' 
 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"