How can I access a class name identically before and after instantiation?

35 Views Asked by At

I'm building an application where I have events defined as python classes. Each event has an explicit type, which I am setting as the name of the class. I have a property defined at .type that allows the developer to access it easily. For example:

class _BaseEvent(BaseModel):
    @property
    def type(self) -> str:
        return self.__class__.__name__

class NamedEvent(_BaseEvent):
    data: str

This has worked great up until recently, where I now require accessing the name of the event before the class is even initialized. I've found some unexpected results trying to do this:

>>> NamedEvent(data=3).type
'NamedEvent'
>>> NamedEvent.type
<property object at 0x7f07fc853a60>
>>> NamedEvent(data=3).__class__.__name__
'NamedEvent'
>>> NamedEvent.__class__.__name__
'ModelMetaclass'
>>> NamedEvent.__name__
'NamedEvent'

Is there a way to have an attribute that returns the event type identically whether it is instantiated or not? I understand that I can check if it's instantiated with isinstance(c, type) but I'm curious if anyone has a cleaner way that doesn't involve a top level function. Or, any advice why that's a bad idea in the first place would be appreciated too.

A function solution:

def getEventType(c: Type[_BaseEvent] | _BaseEvent) -> str:
    if isinstance(c, type):
        return c.__name__
    else:
        return c.__class__.__name__

I've been reading up metaclasses but am in over my head at the moment.

0

There are 0 best solutions below