0

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.

Enty AV
  • 65
  • 4

0 Answers0