Python: Nested Class Inheritance

拟墨画扇 提交于 2019-12-25 06:36:57

问题


Would it be OK to declare an instance of the sub-classed class from its Base (super?) class as I do it here:

if 'classB_args' in dictArg.keys() and dictArg['classB_args']:
    self['classB']=ClassA( dictArg['classB_args'] )

Are there any side effects of doing so? What should I be aware before moving forward. I have a feeling sooner or later something would go wrong... with cPickle , pickle or may be it would be a PyQt drag-and-dropt?.. if so then why would the problem arise?

class Base(dict):
    def __init__(self, *args, **kwargs):
        super(Base, self).__init__(*args, **kwargs)
        self.setdefault('id', -1)
        self.setdefault('name', None)
        self.setdefault('classB', None)

        if not args or len(args)==0: return
        dictArg=args[0]

        if 'classB_args' in dictArg.keys() and dictArg['classB_args']:
            self['classB']=ClassA( dictArg['classB_args'] )

    def getClassB(self):
        return self['classB']

class ClassA(Base):
    def __init__(self, *args, **kwargs):
        if not (args or kwargs):   raise Exception('you need to give me *something*!')
        super(ClassA, self).__init__(*args, **kwargs)
        self.setdefault('win', None)
        self.setdefault('mac', None)

myDictArg= {'id':1, 'name':'MyName', 'win':'c:/windows', 'mac': '/Volumes/mac/', 'classB_args': {'id':1, 'name':'MyProject'}}

myInstance=ClassA(myDictArg)
print myInstance.getClassB()

回答1:


If you're asking whether it will work, the answer is yes, but I can't think of a situation where it is a good idea. The reason is that this locks your base class down to being really only useful with ClassA ... I think that the solution would probably be cleaner to do something like:

myDictArg = {'id':1, 'name':'MyName', 'win':'c:/windows', 'mac': '/Volumes/mac/', 'classB': ClassA(id=1, name='MyProject')}

and forgo all of the extra classB_args craziness in Base.__init__. It's more explicit so the user ends up knowing what to expect.

If you really don't like that, you could use the type of self to determine what to use rather than specifying ClassA directly which is a little better:

self['classB'] = type(self)(dictArg['classB_args'])

Now, if you derive a new class from Base, that will be used instead:

class Foo(Base): pass

instance = Foo(myDictArg)
print type(instance.getClassB())  # Foo !

a few other non-related points.

  1. Don't do x in dct.keys() -- It's horribly inefficient in python2.x. You can just do x in dct :-).
  2. Generally speaking, writing simple wrappers like getClassB are considered "unpythonic". You can just access the data directly in python.
  3. You can rewrite the if clause to clean it up a little:

Here's how:

   if 'classB_args' in dictArg.keys() and dictArg['classB_args']:
        self['classB']=ClassA( dictArg['classB_args'] )

goes to:

   # with this, you can remove the `self.setdefault('classB', None)` statement.
   item = dictArg.get('classB_args')
   self['classB'] = type(self)(item) if item else item


来源:https://stackoverflow.com/questions/22850074/python-nested-class-inheritance

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!