2015-05-03 3 views
2

Я был возился с унаследованными классами и задавался вопросом, можно ли установить атрибут пользовательского объекта с помощью метода. Она будет работать что-то вроде этого:Установить атрибут пользовательского объекта

class MyClass(object): 
    def __init__(self): 
     super.__init__() 
    def setCustAttr(self, name, value): 
     #... 
g=MyClass() 
g.setCustAttr("var",5) 
g.var+=6 
g.var="text" 
  • Есть ли способ сделать это?
  • Не могли бы вы использовать exec("self."+string+"="+value)?
+0

Возможный дубликат [python создать объект и добавить к нему атрибуты] (http://stackoverflow.com/questions/2827623/python-create-object-and -add-attributes-to-it) – felipsmartins

+0

Не обманывать этот вопрос. Этот вопрос касается 'setattr', который не работает на' object'. Скорее всего, это что-то другое. – user2357112

+0

Я предполагаю, что вы имеете в виду в дополнение к 'g.var = 5'? – chepner

ответ

1

Аргументы, передаваемые setCustAttr именно те аргументы, вы передаете в setattr.

def setCustAttr(self, name, value): 
    setattr(self, name, value) 

Почему вы хотите обертку вокруг setattr? Вы можете попробовать выполнить некоторые проверки:

def setCustAttr(self, name, value): 
    if name not in ['bar', 'baz']: 
     raise ValueError("Custom attribute must be 'bar' or 'baz'") 
    if name == 'bar' and value < 0: 
     raise ValueError("'bar' attribute must be non-negative") 
    if name == 'baz' and value % 2: 
     raise ValueError("'baz' attribute must be even") 

    setattr(self, name, value) 

Однако это не мешает пользователю вашего класса от игнорирования вашего метода setCustAttr и назначения непосредственно к объекту:

g = MyClass() 
g.bar = -5 # Negative bar! 
g.baz = 3 # Odd baz! 
g.quux = 2 # Non-bar/baz attribute! 

Python имеет глубокую магию для обеспечения большего контроля над тем, как атрибуты установлены на объекте (см. __slots__, __{get,set}attr__, __getattribute__, свойства и т. д.), но в целом они не используются только для предотвращения приведенных выше примеров. Путь Python заключается в том, чтобы просто документировать, как должен использоваться экземпляр вашего класса, и доверять пользователю соблюдать ваши инструкции. (И если они этого не делают, caveat emptor.)

+0

Значит, не нужно было бы использовать другой метод? – Mutantoe

+0

Не совсем. Вы можете использовать такую ​​оболочку, чтобы обеспечить проверку. 'g.setCustAttr (" var ", 5)' сначала может проверить, что значение больше 0 (поднимая значение ValueError, если нет), или что первый аргумент из ограниченного набора имен (имитирующий часть функции атрибута '__slots__'). Тем не менее, пользователь вашего класса все равно может просто игнорировать ваш метод и написать 'g.var = 5' в любом случае. – chepner

+0

Итак, перед настройкой вы должны оценить новое значение. Благодаря! – Mutantoe

6

Это то, что делает функция setattr:

setattr(g, 'var', 5) 
# g.var is now 5 
Смежные вопросы