Python ООП вопрос про теорию

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?

python



Я бы сделал как-то так:

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






Report Page