简体   繁体   中英

Python class inheritance (multiple) : Why are attributes empty? i.e. doing it right

I'm trying create an intermediate object to work with elsewhere that I can pass in to an sqlalchemy model for creation:

start with:

class IntermediateObj(object):

    def __init__(self, raw):
        self.raw = raw
        self.sections = []
        self.fields = []
        self.elements = []
        super(IntermediateObj, self).__init__()

    def recurse(self, items):
        for k,v in items.iteritems():
            if isinstance(v, list):
                getattr(self, k).append(v)
                [self.recurse(i) for i in v]
            else:
                setattr(self, k, v)

pass to:

class MyClass(IntermediateObj, Base):

    def __init__:(self, attribute=None):
         self.attribute = attribute 
         super(MyClass, self).__init__

eg

ii = IntermediateObj(raw={'large':'nested_dictionary', sections=[{}, {}, {}]})
ii.recurse(ii.raw) #any help smoothing this bit over appreciated as well, but another question...
tada = MyClass(ii)

tada.sections
---> [] /// this should not be, it should correspond to ii.sections

Sections is empty where it should not be, so I don't quite grasp inheritance here yet. This has to be a common question, but I have not found anything I could understand at this point and am just flailing around at various tactics. Any input appreciated on doing python class inheritance correctly.

class IntermediateObj(object):

    def __init__(self, raw):
        self.raw = raw
        self.sections = []
        self.fields = []
        self.elements = []

    def recurse(self, items):
        # this works ok, but passing the same arguments to the recurse function
        # which were passed to the constructor as well ,and then stored as a class
        # attribute, why, seems like self.raw is not even needed?
        for k,v in items.iteritems():
            if isinstance(v, list):
                getattr(self, k).append(v)
                [self.recurse(i) for i in v]
            else:
                setattr(self, k, v)


class MyClass(IntermediateObj):

    def __init__(self, attribute=None):  
        self.attribute = attribute
        super(MyClass, self).__init__(attribute)


ii = IntermediateObj({'large': 'nested_dictionary',
                      'sections': [{}, {}, {}]
                    })
ii.recurse(ii.raw)
print ii.raw
print ii.sections

# passing an instance of IntermediateObj is not the same as passing a dict (logically)
# yet the constructor of MyClass just forwards that instance object to the
# baseclasses constructor, while you initially passed a dict to the IntermediateObj
# constructor. 
tada = MyClass(ii)
# MyClass inherits the recurse method, but it won't magically be executed unless
# you call it, so just instantiating MyClass won't copy those values recursively
tada.recurse(ii.raw)
# now tada, it copied everything, and notice, I called recurse with ii.raw, which is the
# source dictionary, but I'm not even sure if you wanted it that way, it's not clear
# define your question more precisely
print tada.sections

I see you have accepted this as the best answer, and I felt bad about it cause it's not really answered, so I made an update, as we described in the comments, now when an instance of MyClass receives an instance of IntermediateObj, it will call the constructor of the base class with the raw parameter of the passed object. Also recurse is called in IntermediateObj's constructor, so it will copy the values at instantiation time:

class IntermediateObj(object):

    def __init__(self, raw):
        self.raw = raw
        self.sections = []
        self.fields = []
        self.elements = []
        self.recurse(raw)

    def recurse(self, items):
        for k,v in items.iteritems():
            if isinstance(v, list):
                getattr(self, k).append(v)
                [self.recurse(i) for i in v]
            else:
                setattr(self, k, v)


class MyClass(IntermediateObj):

    def __init__(self, intermediate_instance):  
        super(MyClass, self).__init__(intermediate_instance.raw)


ii = IntermediateObj({'large': 'nested_dictionary',
                      'sections': [{}, {}, {}]
                    })
print ii.raw
print ii.sections
tada = MyClass(ii)
print tada.sections
print tada.raw

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM