Зачем использовать __setattr__ в python?
Я не знаю, зачем использовать __setattr__
вместо простой ссылки, например x.a=1
.
Я понимаю этот пример:
class Rectangle:
def __init__(self):
self.width = 0
self.height = 0
x=Rectangle()
x.width=20
x.__setattr__('height',30)
setattr(x,'width',99)
но не получается использовать код в зависимости от строки ('height').
Не могли бы вы объяснить мне, что есть преимущества __setattr__
?
Ответы
Ответ 1
Вы не называете это самим. Период. Если вам нужно использовать строку, потому что вы заранее не знаете ее имя (очень плохая идея в 99% случаев, когда, возможно, это и нужно, почти всегда дикт или список - лучший/более здравый выбор), вы используете встроенная функция setattr
.
Однако он вам нужен - когда вы делаете a.x = ...
, который выполняется как a.__setattr__('x', ...)
(это упрощает упрощение). И некоторые объекты перегружают его, чтобы позволить некоторые обманывать, например. для подражания неизменности. См. документацию по "специальным методам" .
Ответ 2
__setattr__
- метод класса, который вызывается setattr
встроенным методом. То есть, если __setattr__
задан в данном классе. Чаще всего вы не объявляете свою собственную версию __setattr__
, поэтому я предполагаю, что вы спрашиваете, что такое метод setattr
.
Предположим, что у вас есть var с именем атрибута, который вы хотите установить, а не просто зная имя:
class A(object):
def doSth(self, name, val):
setattr(self, name, val)
невозможно сделать с self.name = val
Кроме того, общее использование имеет ключевое слово args:
class A(object):
def __init__(self, *args, **kwargs):
for k,v in kwargs.items():
setattr(self, k, v)
Ответ 3
Я могу представить себе приложение, в котором, например, вы переопределяете __setattr__
и __getattr__
, чтобы предоставить объектный доступ к какой-либо другой структуре данных, которая не хранится в памяти. Например, вы можете создать объект, в котором foo.CustomerName = "John"
обновлен столбец CustomerName
в строке базы данных, на который указывает foo
, чтобы содержать значение "John"
. I.e., foo.__setattr__
будет использовать имя и значение атрибута для создания команды для обновления базы данных на диске. Мне не хотелось бы писать такую вещь, но это было бы возможно.
Ответ 4
Обратите внимание, что __xxx__
являются методами перегрузки операторов класса и как таковые должны использоваться только в особых ситуациях, а не в случаях, как в вашем примере.
Например, __setattr__
перехватывает все назначения атрибутов и может использоваться для изменения поведения вашего класса, когда значение присваивается атрибуту.
Ответ 5
__setattr__
может использоваться для отражения, где при запуске может создаваться призрак на объекте Rectangle, на нем больше 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
Ответ 6
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"
Ответ 7
Первое использование __setattr__
должно быть перезаписано в определении класса.
class Foo ( object ) :
def __init__ ( self ) :
self.x = 'looser'
def __setattr__ ( self, name, value ) :
if name == 'x' :
print( 'Hello, {} !'.format( value ) )
self.x = value
Проблема, Foo()
будет печатать бесконечную последовательность:
'Hello, looser !'
Второе использование - это то, что, когда вы это делаете, вы можете вызвать setattr из родительского класса (object
по умолчанию), чтобы избежать бесконечной рекурсии:
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 ) )
И поэтому:
f = Foo()
>> 'Hello, winner !'
f.x
>> 'winner'