近日切換到python3後,發現python3在多態處理上,有一些比較有意思的狀況,特別記載,供你們參考。。。python
以廖老師的python3教程中的animal 和dog的繼承一節的代碼作例子,上代碼先:ui
#!/usr/bin/env python3 # -*- coding: utf-8 -*- class Animal(object): def run1(self): print('Animal is running 1...') def run2(self): self.run1() print('Animal is running 2...') class Cat(Animal): def run1(self,name): print('[%s] Cat is running1...' %name) def run2(self,name=""): super().run2() print('[%s] cat is running2...' %name) def run_twice(animal): animal.run1("1") animal.run2("2") if __name__=='__main__': c = Cat() run_twice(c)
輸出結果:spa
[1] Cat is running1...
報錯信息以下:debug
 File "d:\python\tensf\clstest.py", line 28, in <module> run_twice(c)  File "d:\python\tensf\clstest.py", line 23, in run_twice animal.run2("2")  File "d:\python\tensf\clstest.py", line 17, in run2 super().run2()  File "d:\python\tensf\clstest.py", line 8, in run2 self.run1() builtins.TypeError: run1() missing 1 required positional argument: 'name'
一、父類animal中run2()調用了run1()code
二、子類cat中覆蓋了run1(),增長了name參數,並覆蓋了run2(),一樣增長了name參數,並調用父類animal中run2()blog
三、理想中的狀態,父類的run2()應該是調用父類的run1(),實際倒是調用子類的run1(),因此致使參數匹配錯誤。繼承
builtins.TypeError: run1() missing 1 required positional argument: 'name'
解決方案要分狀況,就本例而言給name賦上默認值便可。
問題來源於本身寫了configparser的擴展包,實現給get(),getint(),set()加默認值的方法,在python2中好用,移到python3中忽然很差用了,有點發懵。教程
不過仔細分析,仍是python3中configparser的get()有修改。ip
困擾了我接近一天,仍是基本功有問題,貼上我寫的簡單代碼。
補充一點:python3下默認有configparser,無需額外用pip安裝,並且大寫改爲了小寫。utf-8
#coding=utf-8 ''' Date :2016.10.8 Author : joshua zou Purpose : configparser 的擴展類,增長默認值,兼容key不存在的狀況。 Use exap: import eConfig as eTax INICONFIG=eTax.eConfig() #讀取配置文件中配置 debuglevel = INICONFIG.get('default','debuglevel') ''' try: from configparser import OrderedDict as _default_dict except ImportError: # fallback for setup.py which hasn't yet built _collections _default_dict = dict from configparser import RawConfigParser class eConfig(RawConfigParser ): def __init__(self, defaults=None, dict_type=_default_dict, allow_no_value=False): super().__init__(defaults, dict_type,allow_no_value) def get(self, section, option, default='',**kwargs): try : sRet = super().get(section, option,**kwargs) except: sRet = default return sRet def getint(self, section, option,default=None,**kwargs): try : sRet = super().getint(section, option,**kwargs) except Exception as e : sRet = default return sRet def getfloat(self, section, option,default=None,**kwargs): try : sRet = super().getfloat(section, option) except: sRet = default return sRet def getboolean(self, section, option,default=None,**kwargs): try : sRet = super().getboolean(section, option) except: sRet = default return sRet def set(self, section, option,value): if not super().has_section(section): sRet = super().add_section(section) sRet = super().set(section, option, value) return sRet if __name__ == "__main__": #讀取配置 filename = r'zhbook.ini' sf=eConfig() sf.read(filename) print (sf.get('name', 'lastchp','1')) print (sf.getint('name', 'lastchp',0)) print (sf.get('default', 'taskcount1', '1')) print (sf.get('default', 'taskcount1')) print (sf.getint('default', 'taskcount1')) print (sf.getboolean('default', 'taskcount1')) print (sf.getfloat('default', 'taskcount1')) print (sf.set('default2', 'taskcount1',u'2222')) #保存配置 fp = open(filename,"w") sf.write(fp) fp.close() print (sf.get('default', 'taskcount1')) sf.remove_option('default','taskcount1') fp = open(filename,"w") sf.write(fp) fp.close()