Python ООП вопрос про теорию
Для роста своего скила и улучшения понимания, задался вопросом про наследование в Python./ У меня есть два класса: родитель и наследник, имеющие приватный атрибут __n.
class A:
__n = "a"
def __init__(self) -> None:
print(self.__n)
class B(A):
__n = "b"
A()
B()
# a
# a
При наследовании из-за искажения имен доступ к новому значению __n утерян.
Я решаю эту проблему таким способом:
class A:
__n = "a"
def __init__(self) -> None:
print(self.__true_n)
@classmethod
@property
def __true_n(cls):
return getattr(cls, f"_{cls.__name__}__n")
class B(A):
__n = "b"
A()
B()
# a
# b
Хочу разобраться, существует ли более "правильный" или "Питоновский" способ получение доступа к атрибуту __n?
Я бы сделал как-то так:
class A:
__n= "Приват A"
@property
def n(self):
return self.__n
class B(A):
__n = "Приват B"
@property
def nA(self):
return super().n
@property
def n(self):
return self.__n
obj_a = A()
obj_b = B()
print(obj_a.n)
print(obj_b.nA)
print(obj_b.n)
Вывод:
Приват A Приват A Приват B [Program finished]
Пример с использованием metaclass:
import re
class PrivateAccessMeta(type):
def __new__(cls, name, bases, dct):
new_dct = dct.copy()
for key in new_dct.keys():
if key.startswith(f'_{name}') and not key.endswith('__'):
pattern = re.compile(r'_(\w+)__(.*)', re.IGNORECASE)
result = pattern.search(key).group(2)
dct.update({result: property(lambda self, prop=key: getattr(self, prop))})
return super().__new__(cls, name, bases, dct)
class A(metaclass=PrivateAccessMeta):
__n= "Приват A __n"
__z= "Приват A __z"
__y= "Приват A __y"
__h= "Приват A __n"
class B(A, metaclass=PrivateAccessMeta):
__n = "Приват B __n"
obj_a = A()
obj_b = B()
print(obj_a.n)
print(obj_a.z)
print(obj_b.n)
print(obj_b.z)
print(obj_b.y)
Вывод:
Приват A __n Приват A __z Приват B __n Приват A __z Приват A __y