Vitalii Ponomar
Vitalii Ponomar

Reputation: 10936

Python: how to use variables as a string?

Supose I have such variables: var1, var2, var3, var4, var 5, ..., var100 (lists and dictionaries are not suitable in my case, because all these vars are class objects).

I must process all them in similar way, for example:

if var1:
    print 'var1 is not None'
if var2:
    print 'var2 is not None'
if var3:
    print 'var3 is not None'
...
if var100:
    print 'var100 is not None'

In such way I will write 200 hundreds lines of code...

But maybe there is some way to process all of them in for statement, like:

for i in range(1,101):
    if var%s % i: #I know this is not right, but idea is understood
        print 'var%s is not None' % i

So I will write only 3 lines of code.

Is it possible do in Python?

Thanks!

Upvotes: 3

Views: 422

Answers (6)

Sven Marnach
Sven Marnach

Reputation: 601569

You can modify class attributes dynamically:

class A(object):
    pass
for i in range(100):
    setattr(A, "var%i" % i, i)

creates a class with 100 attributes called A.var0 to A.var99. There are two problems with this approach:

  1. The attributes are quite inconvenient to access. (This is possible with getattr(), but having them in a list would make iterating over them so much easier.)

  2. If class A has a custom metaclass, it is unclear how that metaclass deals with the dynamically created attributes.

From a quick glance at the Django source code, I can see that django.db.models.Model indeed has a custom metaclass, and indeed all attributes must already be defined at class creation time, so the above approach won't work. You'll have to create the complete class dictionary before actually creating the class. Here is one approach to do so:

model_dict = {}
for i in range(100):
    model_dict["var%i" % i] = models.CharField(max_length=10)
model_dict["var_list"] = model_dict.values()
MyModel = type("MyModel", (models.Model,), model_dict)

This uses the three-parameter form of type() to dynamically create a type. This part addresses problem 2.

To address problem 1, the above code exposes also adds an attribute to the class that allows to acces all the models.CharField instances as a list rather than by name.

Upvotes: 2

Josh Imhoff
Josh Imhoff

Reputation: 6946

I think that a list or dictionary actually would be the most appropriate way to solve your problem. In Python, data structures can hold others objects. This includes objects that you create yourself because there is no technical distinction from the programmer's point of view between the types (classes) you define and the ones that are native to Python (string, int, etc.)

Upvotes: 1

Kyle G
Kyle G

Reputation: 1038

Couple different ways to do it, either get the variable from the globals or locals dictionary like so: globals()['var1']

or import __main__ and use getattr(__main__,'var1')

throw those into a for loop, assigning the variable name to a string andhave it returned eg

if your testing that the class exists, use a try except

import __main__

for i in range(1,101):
  try:
    func = getattr(__main__,'var%s' % i)
    if func is not None:
      print 'var%s is not None' % i
  except:
    print 'var%s does not exist'

if it's buried in a class use the class name rather than __main__. If the class name is var%s use getattr on func in the loop above to grab whatever it is you need out of each class.

Upvotes: 1

Maecky
Maecky

Reputation: 2038

I think you are looking for the eval command.

Hope this helps,

Regards, Maecky

Upvotes: 2

Daniel Roseman
Daniel Roseman

Reputation: 599580

I wish you hadn't buried your actual requirement in the tenth comment underneath the main question. Actually, it appears that what you want is to dynamically get a property of a class - in this instance, a field in a Django model. That's simple: you just do:

getattr(instance, varname)

Upvotes: 5

kichik
kichik

Reputation: 34704

locals() returns a dictionary of local variables. Similarly, globals() returns a dictionary of global variables. You can find the variable and its value in one of those, depending on where it was defined.

for i in range(1,101):
    if ('var%s' % i) in locals():
        print 'var%s is not None' % i
        print locals()['var%s' % i]

Upvotes: 8

Related Questions