0

Given a class type, I'd like to get its name and print it to console. I have access to the class type but not an instance.

class Foo:
  pass

def print_class_names(klass):
   print(klass.__some_dunder?__) # don't know how to do this

print_class_name(Foo) # would like this to print "Foo"

Bonus: I would also like to access inherited types and generic type, so, for example, if I have list[Foo] I could access "list" and "Foo" as separate strings.

I can directly print the class like print(Foo) but that gives me <class '__main__.Student'> and I'd like to avoid string manipulation if possible.

jacob_g
  • 674
  • 8
  • 21
  • Are you saying that you want to see ```Student``` rather than ``````? – jtb Mar 17 '23 at 17:05
  • 1
    It's very important to understand, `list[str]` **is not a type**. `list` is a type. `list[str]` is a type annotation. Anyway, given an actual type (i.e. a class) then you just want `klass.__name__`. – juanpa.arrivillaga Mar 17 '23 at 17:06
  • 1
    Strictly speaking, `list[str]` is an expression whose value is an instance of `types.GenericAlias`. It behaves much like `list` at runtime, for example, `list[str]()` returns an empty list, the same as `list` itself. – chepner Mar 17 '23 at 17:08
  • If `klass` is a `GenericAlias`, it looks like the underlying type is `klass.mro()[0]` and the "argument(s)" are available from `klass.__args__`. I suspect this is somewhat fragile, though. – chepner Mar 17 '23 at 17:12
  • @chepner yeah, you want to use the function in `typing`, so `typing.get_args` and `typing.get_origin` – juanpa.arrivillaga Mar 17 '23 at 17:15
  • Ah, thanks. If I had noticed they existed, I had certainly never looked at what they were for. – chepner Mar 17 '23 at 17:31
  • 1
    `__name__` works for my purposes, thanks all – jacob_g Mar 17 '23 at 18:19

0 Answers0