4

I don't know how many class instances I will have from the get-go, so I need to create them dynamically, but I would also like to keep the code tidy and readable.

I was thinking of doing something like this:

names = ['Jon','Bob','Mary']

class Person():
    def __init__(self, name):
        self.name = name

people = {}
for name in names:
    people[name] = Person(name)

It works, but I can't seem to find any examples of people doing this online (though I didn't look much). Is there any reason I should avoid doing this? If so, why and what is a better alternative?

hochl
  • 12,524
  • 10
  • 53
  • 87
TimY
  • 5,256
  • 5
  • 44
  • 57
  • 5
    for what I see, you are talking about creating **objects** dynamically, instead of **classes**, am I right? – Jonas Schäfer Oct 01 '12 at 13:19
  • You mean creating class instances dynamically?? – Rohit Jain Oct 01 '12 at 13:19
  • 3
    In the code above, you don't create any classes dynamically, only one class `Person` is defined, then three instances of it are created. That's a perfectly legitimate way of doing that, can't see any problem. – bereal Oct 01 '12 at 13:20
  • Yes, you are correct. I'm sorry I mixed up my terminology. – TimY Oct 01 '12 at 23:53

3 Answers3

5

If you want to create class instances dynamically, which is exactly what you are doing in your code, then I think your solution looks perfectly fine and is a pythonic way to do so (although I have to say there are of course other ways). Just to give you some food for thought: you could register/store each new instance with the class like that:

class Person():
    people={}
    @classmethod
    def create(cls,name):
        person=Person(name)
        cls.people[name]=person
        return person
    def __init__(self, name):
        self.name = name

And if you are getting adventerous, you can try the same with metaclass, but I will leave that for your research :-)

schacki
  • 9,401
  • 5
  • 29
  • 32
3

Use type(name, bases, dict)

From documentation:

Return a new type object. This is essentially a dynamic form of the class statement. The name string is the class name and becomes the name attribute; the bases tuple itemizes the base classes and becomes the bases attribute; and the dict dictionary is the namespace containing definitions for class body and becomes the dict attribute. For example, the following two statements create identical type objects:

>>> class X(object):
...     a = 1
...
>>> X = type('X', (object,), dict(a=1))

For your example:

>>> JonClass = type('JonClass', (object,), {'name': 'Jon'})
>>> jon_instance = JonClass()
>>> jon_instance.name
'Jon'
>>> type(jon_instance)
<class '__main__.JonClass'>
defuz
  • 26,721
  • 10
  • 38
  • 60
1

How about using a generator expression to create the dictionary?

people = dict((name, Person(name)) for name in names)

But besides this your solution is perfectly valid.

hochl
  • 12,524
  • 10
  • 53
  • 87