Запретить совместное использование переменных класса с базовым классом в Python - PullRequest
0 голосов
/ 01 июня 2018

У меня следующая ситуация в Python 3:

class A:
    d = {}

class B(A):  pass
class C(A):  pass

Я работаю только с классами, экземпляры не создаются.Когда я получу доступ к B.d, я получу общую ссылку на A.d.Это не то, что я хочу.Я хотел бы, чтобы каждый класс, который наследует A, имел свой собственный d, который установлен в словарь.d является подробностью реализации A.Весь доступ к d осуществляется в коде A.Просто B d не должно совпадать с A d.

В случае экземпляров я бы создал этот словарь в функции __init__().Но в моем случае я работаю только с классами.

Существует ли стандартный способ достижения этого (РЕДАКТИРОВАТЬ: без изменения реализации подклассов B и C)?Есть ли что-то аналогичное __init__(), которое вызывается (или в) для каждого производного класса во время создания?

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Я сам нашел решение, используя метакласс:

class M(type):
  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.d = {}

class A(metaclass=M): pass

Затем можно создать подклассы A, которые имеют собственный атрибут d:

class B(A): pass

B.d is A.d
False
0 голосов
/ 01 июня 2018

Просто тестируем @meissner_ комментарий: вы можете легко заменить d внутри ваших подкалок на другие.

class BaseA():
    """Provides basic initialization for dicts used in A() and deriveds."""
    @classmethod
    def InitDefaults(cls):
        return { 1: "this", 2:"are", 3:"some", 4:"defaults"}

class A():
    d = BaseA.InitDefaults()

class B(A):
    d = BaseA.InitDefaults()

class C(A):
    d = BaseA.InitDefaults()


print(A.d)
print(B.d)
print(C.d)

print("\n")
B.d[99] = "Not a default"
C.d[42] = "Not THE answer"

print(A.d)
print(B.d)
print(C.d)

Вывод:

{1: 'this', 2: 'are', 3: 'some', 4: 'defaults'}
{1: 'this', 2: 'are', 3: 'some', 4: 'defaults'}
{1: 'this', 2: 'are', 3: 'some', 4: 'defaults'}


{1: 'this', 2: 'are', 3: 'some', 4: 'defaults'}
{1: 'this', 2: 'are', 3: 'some', 4: 'defaults', 99: 'Not a default'}
{1: 'this', 2: 'are', 3: 'some', 4: 'defaults', 42: 'Not THE answer'}

Это немного уродливо, ноРабота.У вас есть центральное место для кода, модифицирующего «base-default», и A, B, C получают разные диктовки - инициированные одинаково - которые могут развиваться в разных направлениях.

Вероятно, лучше было бы использовать Instances и init () хотя ...

...