Inheriting and Combining Class Attributes

Simple example:

class A:
    attr = {'a': 1}

class B(A):
    attr = {'b': 2} #overrides A.attr

      

What I want is a dictionary aggregation method. I can only think of these options:

  • Ignore this unpleasant feeling and copy everything by hand.
  • Manually adding dictionaries:

    class B(a):
        attr = dict(list(six.iteritems(A.attr)) + list(six.iteritems({
            'b': 2
        })))
    
          

    Note 'b': 2

    should be the second, so its keys will be shadow A

    .

    It should state it explicitly A

    ( is there a way to get this using super

    ?
    ). It also needs micro-inheritance to be applied manually.

  • This can also be achieved with metaclasses. I've seen this done DeclarativeFieldsMetaclass

    in django
    . The idea is to merge the metaclass dictionary for a specific attribute.

    This is much more work. Also, since it introduces magic that doesn't normally happen in python, it might be considered a bad option. I also prefer not to use metaclasses if needed to avoid conflicts.

    One of the main advantages is that the user does not need to manually aggregate the attribute data.

Is there another way?

I would like to know what others think of each approach regarding good programming practice.

In my case I am using MultiModelForm

from django-betterforms
and has a basic form with several ModelForm

but want to expand it. I don't think that the inherited class should duplicate ModelForm

in the attribute form_classes

from the parent.

Should the user manage inheritance as in Option 2, or should it MultiModelForm

handle it automatically with a metaclass as in Option 3? Are there other issues with each option that I haven't discussed?

+3


source to share


2 answers


You can do this using a dictionary.update()

function that will add a new dictionary to the existing one

Example

>>> class A:
...     attr = {'a': 1}
... 
>>> class B(A):
...     attr = dict(A.attr)
...     attr.update({'b' : 2 })
... 
>>> 
>>> A.attr
{'a': 1}
>>> B.attr
{'a': 1, 'b': 2}

      



What is he doing?

  • attr = dict(A.attr)

    returns a new dictionary from A.attr

    . This is important because if we write

    attr = A.attr
    
          

    we will end up updating the attr

    class A

    instead of the class B

    .

  • attr.update({'b' : 2 })

    Updates B.attr

    by adding a new dictionary {'b' : 2 }

    .

+6


source


This works for me:



class A:
    attr = {'a': 1}

class B(A):
    attr = dict({'b': 2}.items() + A.attr.items())

      

+4


source







All Articles