I've faced an issue when tried to write a module for adding options to different classes. Here is the code:
import copy
from itertools import chain
from future.utils import with_metaclass, iteritems
class Option(object):
def __init__(self, val):
self.__set__("", val)
def __set__(self, instance, value):
self.value = value
def __get__(self, instance, owner):
return self.value
class OptionsAggregator(type):
def __new__(cls, name, bases, attrs):
try:
external_attrs = chain([base.external for base in bases])
except AttributeError:
attrs['external'] = {}
else:
attrs['external'] = {k: v for d in external_attrs for k, v in iteritems(d)}
for key, value in iteritems(attrs.copy()):
if isinstance(value, Option):
attrs['external'].update({key.lower(): value.value})
return super(OptionsAggregator, cls).__new__(cls, name, bases, attrs)
class Options(with_metaclass(OptionsAggregator, object)):
pass
class A(Options):
var1 = Option("sas")
def acheck(self):
print(self.var1)
class C(A):
def __init__(self):
super().__init__()
def check(self):
print(self.external)
c = C()
v = copy.deepcopy(c)
v.var1 = 1
n = copy.deepcopy(c)
n.var1 = 4
v.acheck()
n.acheck()
The result I am expecting is:
1
4
But even after copying class the result is:
4
4
How can I copy C
class so for each copy there is new A
with new var1
. If it is possible, I want class A
stay the same.
Moreover, I can't move var1
into __init__
because if I do this, then OptionsAggregator
won't be able to see this attribute (in attrs
) and won't add it to self.external
.
So, generally my question is: How to deepcopy class if its attribute is not under __init__
function.
Thanks in advance.