I have a class that declares a property in Python, the default implementation for this method is pass
, for example:
class A:
@property
def something(self):
pass
This property is intended to declare a functionality for extending classes, and I want to use it to declare a field, where if extending classes implemented it, the field is initialized to some value, and if they don't then the value of the field is None
.
How can I check if users did implement it?
I tried using __code__
and hasattr()
but that didn't work.
Check in the initialiser, where you are setting the default value for the attribute, if the something
property has been modified on the instance's class or if it is unmodified from the base class's implementation and set the attribute's value based on the result of that check:
from __future__ import annotations
class A:
def __init__(self) -> None:
self.attribute = None if type(self).something is A.something else 'Initialised'
@property
def something(self) -> str | None:
pass
class B(A):
@property
def something(self) -> str | None:
return "X"
class C(A):
@property
def something(self) -> str | None:
print("Has side-effect")
return None
class D(A):
...
print(f"A: {A().attribute}")
print(f"B: {B().attribute}")
print(f"C: {C().attribute}")
print(f"D: {D().attribute}")
Which outputs:
A: None
B: Initialised
C: Initialised
D: None
Alternatively, you could use a property to check each time the attribute is queried:
class A:
@property
def attribute(self) -> None:
return None if type(self).something is A.something else 'Initialised'
@property
def something(self) -> str | None:
pass
Or, if you want a class attribute (rather than an instance attribute), set the attribute on the sub-class in __init_subclass__
:
class A:
attribute: str | None = None
def __init_subclass__(cls) -> None:
cls.attribute = None if cls.something is A.something else 'Initialised'
@property
def something(self) -> str | None:
pass