2014-04-03 189 views
0

难道是OK从其基地(超?)类声明子类的类的实例,因为我在这里做:的Python:嵌套类继承

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

是否有这样做的任何副作用所以?在继续前进之前我应该​​知道些什么。我有一种感觉迟早会出现问题......用cPickle,pickle或者可能是PyQt拖放?如果是的话,那么为什么会出现问题?

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

[XY问题(HTTP:// meta.stackexchange.com/a/66378/174568)... – ekhumoro

+0

你的代码中没有嵌套类,所以你的问题的标题是误导性的。 – martineau

回答

1

如果你问它是否会工作,答案是肯定的,但我不能想到这是一个好主意的情况。其原因是,此功能会锁定你的基类降低到是真的只用ClassA有用......我认为,解决办法可能是更清洁做这样的事情:

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

,并放弃所有的额外classB_args疯狂的Base.__init__。它更加明确,所以用户最终知道期望什么。

如果你真的不喜欢,你可以使用的self的类型来决定使用什么,而不是指定ClassA直接这是一个好:

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

现在,如果你得出从Base一个新的类,将被用来代替:

class Foo(Base): pass 

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

AF其他非相关点。

  1. 不要做x in dct.keys() - 在python2.x中这是非常低效的。你可以做x in dct :-)。
  2. 一般来说,编写简单的包装如getClassB被认为是“unpythonic”。你可以直接在python中访问数据。
  3. 您可以重写if条款把它清理干净一点:

方法如下:

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

去:

# 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 
+0

感谢您的了不起的信息! – alphanumeric

+0

经过测试后,不幸的是我仍然不清楚类型(自我)(项目)的语法和目的。请你澄清它是什么....先谢谢了! – alphanumeric

+0

'type(self)'返回与实例关联的类。因此,例如,如果您使用子类“classA()”调用此类型,则“type(self)”将是“classA”。如果你创建'Base'' ClassB'的另一个子类(例如'class ClassB(Base):...'),那么'type(self)'将会是'ClassB'。 – mgilson