5

How to use a string containing a class name to reference a class itself?
See this (not working) exemple...

class WrapperClass:
    def display_var(self):
        #FIXME: self.__class_name__.__name__ is a string
        print self.__class__.__name__.the_var

class SomeSubClass(WrapperClass):
    var = "abc"

class AnotherSubClass(WrapperClass):
    var = "def"

And an obvious error message:

>>> b = SomeSubClass()
>>> b.display_var()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 4, in display_var
AttributeError: 'str' object has no attribute 'the_var'
>>> 

Thanks!

4 Answers 4

10

How to use a string containing a class name to reference a class itself?

Classes aren't special, they're just values contained in variables. If you've said:

class X(object): pass

in global scope, then the variable ‘X’ will be a reference to the class object.

You can get the current script/module's global variables as a dictionary using ‘globals()’, so:

classobj= globals()[self.__class__.__name__]
print classobj.var

(locals() is also available for local variables; between them you shouldn't ever need to use the awful eval() to access variables.)

However as David notes, self.__class__ is already the classobj, so there's no need to go running about fetching it from the global variables by name; self.__class__.var is fine. Although really:

print self.var

would be the usual simple way to do it. Class members are available as members of their instances, as long as the instance doesn't overwrite the name with something else.

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

2 Comments

hmmm: " the variable ‘X’ will be a reference " Not precisely. The identifier "X" is class object itself, and can be used anywhere a constant would be used.
Indeed. What I'm trying describe in clumsy English is that while X is the class object, it really is just a reference; if you assigned something else to “X” then it would no longer be. The important point is that in Python, the name ‘X’ does not become special; it is just another variable.
3

Depending on where you get this string, any general method may be insecure (one such method is to simply use eval(string). The best method is to define a dict mapping names to classes:

class WrapperClass:
    def display_var(self):
        #FIXME: self.__class_name__.__name__ is a string
        print d[self.__class__.__name__].the_var

class SomeSubClass(WrapperClass):
    the_var = "abc"

class AnotherSubClass(WrapperClass):
    the_var = "def"

d = {'WrapperClass': WrapperClass, 'SomeSubClass': SomeSubClass, 'AnotherSubClass': AnotherSubClass}
AnotherSubClass().display_var()
# prints 'def'

Comments

2

Your example would work if you called print self.__class__.var. I don't think there's any need to use the name.

1 Comment

Appearently not, why would he ask if he knew the answer?
0

There exists a case where one has the name of a class, but not a reference to it. A tkinter Entry widget has a validate method which returns to the callback function (%W parameter) the name of the widget, not a reference to it. If you have a window with an array of entry fields, It is inconvenient to use a different callback function for each entry. Converting the string name to the reference in the callback function is a more efficient way to associate the callback to the source of the validate event. I would have commented on Devin's answer, but don't have the reputation points to make comments yet.

Comments

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.