I have the following situation in Python 3:
class A:
d = {}
class B(A): pass
class C(A): pass
I work with the classes only, no instances get created. When I access Bd
I will get a shared reference to Ad
. That's not what I want. I would like to have each class which inherits A
have its own d
which is set to a dictionary. d
is an implementation detail to A
. All access to d
is done in the code of A
. Just B
's d
should not be identical to A
's d
.
With instances, I would create that dictionary in the __init__()
function. But in my case I work with the classes only.
Is there a standard way to achieve this (EDIT: without changing the implementation of the subclasses B
and C
)? Is there something analog to __init__()
which gets called for (or in) each derived class at the time of deriving?
I found a solution myself using a metaclass:
class M(type):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.d = {}
class A(metaclass=M): pass
Then one can create subclasses of A
which all have their own d
attribute:
class B(A): pass
B.d is A.d
False
Simply testing @meissner_ comment: you can easily replace the d
inside your subcalsses by other ones.
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)
Output:
{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'}
This is kinda ugly but would work. You have a central place for code modifying the "base-default" and A,B,C get distinct dicts - initted the same - that can develop into different directions.
Probably better would be to use Instances and init () though ...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.