0

I have a list of class names as strings, and if I say fe. print(cNames[0]) it will result into Foo since cNames[0] = "Foo". Now if I wanted to compare a class string with a class, I would do this:

if eval(cNames[0]) in classes:
    foo = eval(cNames[0])()

How ever, it's giving me invalid syntax error:

  File ".\testing.py", line 54, in convert
    print("Class: %s" %eval(cNames[0]))
  File "<string>", line 1
    <class 'testing.Foo'>
    ^

SyntaxError: invalid syntax

And I know I'm only printing the class name, but it didn't work for if sentence either, so I tried to do it with a print. No effect

EDIT: So the problem appeared to be me calling eval("<class 'testing.Foo'>") instead of eval("Foo"). Now this leads into few problems, I'm working with sqlite3 database and I'm trying to save a string as following: <class>:i for example Foo:53, but instead I'm doing <class 'testing.Foo'>:53, and that's why calling eval on it wouldn't work. How could I turn <class 'testing.Foo'> (not a string, the class itself) into string "Foo"?

12
  • 4
    eval() is generally a bad idea. Commented Oct 14, 2012 at 10:41
  • 2
    can't you do it with getattr(globals(), cNames[0])? Commented Oct 14, 2012 at 10:42
  • Why's that? How should I compare class string with a class then? Commented Oct 14, 2012 at 10:42
  • also, is this py3? you use print as a function, not a statement Commented Oct 14, 2012 at 10:44
  • 1
    Can you post the full code please? Also, you can't use gettattr on lists, because the objects they store are not their attributes. You can use L[L.index(obj)] or something as alternative Commented Oct 14, 2012 at 10:48

2 Answers 2

3

I'm pretty sure what is happening here is you are doing the eval() twice - and that cNames[0] is the representation you get of the class when you print it. That is, you are doing:

eval("<class 'testing.Foo'>")

I will say, however, this is a bad way of doing it. Store a dictionary which goes from name to class and use that - it's the clearer, more reliable, safer, faster method (you can generate this dictionary if you really feel it's needed).

Sign up to request clarification or add additional context in comments.

2 Comments

You should do the eval not even once.
Of course - my first comment on the question was saying that, but I'm explaining why it doesn't work - whether it's a terrible idea or not.
2

Assuming you have a list containing your classes, you can do this quite tidily without using eval

class Foo(object):
    pass

class Thing(object):
    pass

# List of interesting classes
classes = [Foo, Thing]

# Construct a dictionary where the key is the Classes __name__ attribute
classByNames = {cls.__name__:cls for cls in classes}

# Example usage
cName = 'Foo'
if cName in classByNames:
    inst = classByNames[cName]()
    print(inst) # <__main__.Foo object at ...>
else:
    print("Unknown class %s" % cName)

(only tested the above in Python v2.7, but should work fine in v3 also)

Comments

Your Answer

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