48

Let's say I create an instance of a class and want to assign some values to its public properties. Usually, this would be done like this:

class MyClass:
    def __init__(self):
        self.name = None
        self.text = None

myclass = MyClass()
myclass.name = 'My name'

But, what if a write a function that takes a class as parameter and I would like to assign some values to the public properties of that class dynamically - that is via variables and loops (without knowing how many there are or what they are called.)

The obvious would be:

myclass = MyClass()
myclass['name'] = "My name"

But that doesn't work.

Any ideas?

1

4 Answers 4

57
setattr(my_class_instance, 'attr_name', attr_value)
Sign up to request clarification or add additional context in comments.

Comments

21

After reading rejected Syntax For Dynamic Attribute Access I'm using a mixin class providing dictionary-style access to an object's attributes :

class MyClass:
    def __init__(self):
        self.name = None
        self.text = None
    def __getitem__(self, name):
        return getattr(self, name)
    def __setitem__(self, name, value):
        return setattr(self, name, value)
    def __delitem__(self, name):
        return delattr(self, name)
    def __contains__(self, name):
        return hasattr(self, name)

While still being able to set attributes directly:

myclass = MyClass()
myclass.name = "foo"
myclass.text = "bar"

it's then possible to set them dynamically :

for attr in ('name', 'text'):
    myclass[attr] = confirm(attr, default=myclass[attr])

1 Comment

I only needed the def __getitem__ two lines in my case. Worked great!
2

Using dir with setattr should do the job

class MyClass:
  def __init__(self):
    self.name = None
    self.text = None

myclass = MyClass()
myclass.name = 'My name'

for prop in dir(myclass):
    print '%s:%s'%(prop,getattr(myclass,prop))

print

for prop in dir(myclass):
    if prop[:2]!='__' and prop[-2:]!='__':
        print prop[-2:]
        setattr(myclass,prop,"Foo Bar")

for prop in dir(myclass):
    print '%s:%s'%(prop,getattr(myclass,prop))    

But be careful because this code also sets '__doc__', '__init__', '__module__' properties to "Foo Bar". So you will have to take care of avoiding certain things given to you by dir (especially those which start and end with __ double underscores).

Comments

1

I don't know if this solution is a good or bad idea. But this works for me.

myclass = MyClass()
myclass.__dict__['name'] = "My name"

2 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
I don't have enough reputation to upvote an answer, but I would upvote this answer. Its the simplest and worked for exactly what a needed. I was trying to allow user to set loglevel in logging module obtained via parsed argument, and the following worked perfectly: logging.__dict__[loglevel]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.