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.