1

I have a case where the "names" of classes of interest are available.

Is it possible, without creating an instance of the class, to check for the existing and value of Class attributes ?

E.g., I know that one can do this

class Universal:
    answer = 42

all_knowing_one_class = Universal
solution = 'answer'
unknown = 'a great mystery'
print('The universal answer is', getattr(all_knowing_one_class, solution, unknown) )

But not clear how to do this if one starts with the string name of the class

class Universal:
    answer = 42

all_knowing_one_class_name = 'Universal'
solution = 'answer'
unknown = 'a great mystery'
print('The universal answer is', ??? )

I know that I could create a local mapping between name and class, but wondered if there was a more pythonic way that I could learn :-)

  • Welcome to Stack Overflow. "E.g., I know that one can do this... But not clear how to do this if one starts with the string name of the class" Okay; so then the question is **not about** getting the attribute from the class; it's **only** about getting the class itself from its string name. Once you have that, you have it; and getting attributes from it, clearly, works the same way as before. Please read [ask] and try to focus questions on the relevant part. – Karl Knechtel Oct 21 '22 at 01:05
  • I don't agree with the dupe closure because the dupe suggestions only show how to use `getattr` when a reference to the target is already held, and the O.P. clearly already knows about `getattr`'s basic usage since it was used in the question already. – wim Oct 21 '22 at 01:06
  • @wim the first target I showed very explictly goes over that material: the answers explain that you can either build your own structure to reference the target (such as a dictionary), or get a namespace with `locals()` (or `globals()`, etc. depending on what is appropriate to the situation and then do a normal lookup from there. That said, we ought to have a more general canonical that talks about attribute-namespaces vs. dict-namespaces, and how to get a hold of them. – Karl Knechtel Oct 21 '22 at 01:09
  • Hmm, I was looking at the top-voted and accepted answer, but I see now that the [second answer](https://stackoverflow.com/a/47496649/674039) does demonstrate accessing `locals()`. Though perhaps it's not bad to have a more tailored answer here - it may not be immediately obvious that the object created by a class definition block is also just a variable in some namespace somewhere. – wim Oct 21 '22 at 01:17

1 Answers1

0

You don't need to create a local mapping between name and class, because such a mapping already exists - locals(). The dynamic namespace lookup can be done with either getitem or getattr style access: it's getattr if you have the module instance itself, and getitem if you have the namespace (i.e. the module's __dict__).

If you're working within the same namespace:

the_class = locals()[all_knowing_one_class_name]

# or...

import __main__
the_class = getattr(__main__, all_knowing_one_class_name)

If the Universal class is defined in a different namespace, other_module.py say:

import other_module

the_class = vars(other_module)[all_knowing_one_class_name] 

# or

the_class = getattr(other_module, all_knowing_one_class_name)

If the name of "other_module.py" is also dynamic:

import importlib
other_module = importlib.import_module("other_module")
wim
  • 338,267
  • 99
  • 616
  • 750