Предположим, у меня есть объект Python x и строка s, как мне установить атрибут s на x? Так:
>>> x = SomeObject()
>>> attr = 'myAttr'
>>> # magic goes here
>>> x.myAttr
'magic'
Что за магия? Цель этого, кстати, состоит в том, чтобы кэшировать вызовы x.__getattr__().






setattr(x, attr, 'magic')
Для получения помощи:
>>> help(setattr)
Help on built-in function setattr in module __builtin__:
setattr(...)
setattr(object, name, value)
Set a named attribute on an object; setattr(x, 'y', v) is equivalent to
``x.y = v''.
Обновлено: Однако вы должны отметить (как указано в комментарии), что вы не можете сделать это с «чистым» экземпляром object. Но, скорее всего, у вас есть простой подкласс объекта, с которым он будет работать нормально. Я настоятельно рекомендую ОП никогда не создавать экземпляры таких объектов.
Совершенно верно, это не так. Я для удобства проигнорировал это. Я настоятельно рекомендую ОП никогда не создавать экземпляры таких объектов.
Черт возьми, это работает не во всех случаях, так как это было бы действительно полезно, например, для добавления атрибута dirty к пользовательскому вводу ...
@Brice: setattr работает почти во всех случаях. По соображениям эффективности и по другим причинам «объект» запрограммирован так, что вы не можете добавлять к нему дополнительные атрибуты. Вы можете сделать это с вашим собственным классом с атрибутом __slots__.
Это также не работает на int. Вы можете объяснить почему? (это на всех __builtin__?
@JensTimmerman: Практически, потому что целые числа должны быть неизменными. Реализация стажеры небольших целых чисел, строк и некоторых других встроенных неизменяемых типов. Если бы вам было разрешено устанавливать произвольные атрибуты для этих типов, это интернирование нарушило бы множество тонких и запутанных способов.
Можно ли создать подкласс int, используя шаблон type(cls, (int,), kwargs)? (Я создаю подклассы float на регулярной основе и заменяю __init__ в настраиваемом поплавке, чтобы добавить настраиваемые атрибуты)
Обычно для этого мы определяем классы.
class XClass( object ):
def __init__( self ):
self.myAttr= None
x= XClass()
x.myAttr= 'magic'
x.myAttr
Однако до некоторой степени это можно сделать с помощью встроенных функций setattr и getattr. Однако они не работают напрямую с экземплярами object.
>>> a= object()
>>> setattr( a, 'hi', 'mom' )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'hi'
Однако они работают со всеми видами простых классов.
class YClass( object ):
pass
y= YClass()
setattr( y, 'myAttr', 'magic' )
y.myAttr
Любое понимание, почему это не работает с экземплярами object ()?
@meawoppl Вы должны спросить это как новый вопрос
могу я сделать это с модулями вместо классов?
Ссылка в комментарии @ jalanb - 404.
пусть x будет объектом, тогда вы можете сделать это двумя способами
x.attr_name = s
setattr(x, 'attr_name', s)
Также отлично работает в классе:
def update_property(self, property, value):
setattr(self, property, value)
Однако будьте осторожны, это не работает в вашем сценарии, где вы создаете экземпляр object ().