2014-04-03 187 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