4

I'm tring to create class instances in a loop. All instances need to be assinged to a different variable. These variables can be a sequence of letters like [a,b,c].

class MyClass(object):
    pass

for i in something:
    #create an instance

If the loop turns 3 times, I want the loop make something like that:

a = MyClass()
b = MyClass()
c = MyClass()

Is there a way to do that?

Hzyf
  • 1,007
  • 2
  • 12
  • 21
  • 5
    So you don't want a list of instances? Is there a reason for that? – Lev Levitsky May 20 '12 at 14:11
  • 1
    `instances = [MyClass() for i in range(N)]` for all practical purposes, `instances[0]` through `instances[N-1]` are different variables. The fact that you are asking how to do this suggests that you are approaching the problem in the wrong way. What is it exactly, that you would like to do with these instances? – Joel Cornett May 20 '12 at 14:37

6 Answers6

9

Using independent variable names this way is a bit odd; using either a dict or a list, as shown above, seems better.

Splitting it down the middle, how about

a,b,c = (MyClass() for _ in range(3))
Hugh Bothwell
  • 55,315
  • 8
  • 84
  • 99
  • 2
    +100 This question is a fantastic example of why letting the inexperienced choose the 'right' answer is a ridiculous notion. – Matthew Trevor May 21 '12 at 07:09
2

You can do this using exec. See also Modifying locals in Python

>>> class Foo(object): pass
... 
>>> for name in "abc":
...     exec "{0} = Foo()".format(name)
... 
>>> a
<__main__.Foo object at 0x10046a310>
>>> b
<__main__.Foo object at 0x10046a390>
>>> c
<__main__.Foo object at 0x10046a3d0>
Community
  • 1
  • 1
robert
  • 33,242
  • 8
  • 53
  • 74
1

You could create a list holding all the instances. For instance:

instances = [MyClass() for i in range(0, N)]
betabandido
  • 18,946
  • 11
  • 62
  • 76
1

Not easily, it's generally a bad idea to do something like that; someone else can elaborate why, because it's not really clear to me.

What you might do instead is

class MyClass(object):
    pass

list_of_insts = []
for i in something:
    #create an instance
    lists_of_insts.append(MyClass())

Then you can refer to each positionally in that list: lists_of_insts[0]. You could also assign them to a dict instead of a list for easier access.

TankorSmash
  • 12,186
  • 6
  • 68
  • 106
1

you could have a list of the names you want to name the objects and then in the loop you add the names to the global namespace as you create and name the objects.

list_of_names = ['a', 'b', 'c', 'd']
for name in list_of_names:
    globals()[name] = your_object()

People here will definitely say this is a bad way to code without giving any cogent reason but it directly solves your problem without any further list or dict.

cobie
  • 7,023
  • 11
  • 38
  • 60
  • 1
    The "cogent reason" is that globals() is bound to the module where the code is defined, not where the code is called, an important distinction that isn't always clear to new users. In small all-in-one-module code examples like yours, there's not much chance of an issue. But if you defined your assignment factory somewhere else, it would fail. This is 100% _not_ the right way to do this, it's just really bad coding practice. – Matthew Trevor May 21 '12 at 07:09
0

How about storing those variables in a dict? Like

variables = {}
varnames = ['a', 'b', 'c']
for i, something in enumerate(things):
    variables[varnames[i]] = MyClass()
blurrcat
  • 1,278
  • 13
  • 23
  • 1
    Don't use `vars` as variable name as it is a built-in function – Zeugma May 20 '12 at 14:15
  • 1
    Why the enumeration instead of `for varname in varnames:`? – DSM May 20 '12 at 14:20
  • @DSM According to the example given by the question, the loop should be controlled by `something` or in this example `things` rather than `varnames`. – blurrcat May 20 '12 at 14:24