论python3下“多态”与“继承”中坑

Posted 朝花夕拾

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了论python3下“多态”与“继承”中坑相关的知识,希望对你有一定的参考价值。

1、背景:

近日切换到python3后,发现python3在多态处理上,有一些比较有意思的情况,特别记载,供大家参考。。。

以廖老师的python3教程中的animal 和dog的继承一节的代码做例子,上代码先:

#!/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)

 

输出结果:

[1] Cat is running1...

报错信息如下:

? 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

2、分析原因:

1、父类animal中run2()调用了run1()

2、子类cat中覆盖了run1(),增加了name参数,并覆盖了run2(),同样增加了name参数,并调用父类animal中run2()

3、理想中的状态,父类的run2()应该是调用父类的run1(),实际却是调用子类的run1(),所以导致参数匹配错误。

builtins.TypeError: run1() missing 1 required positional argument: name

解决方案要分情况,就本例而言给name赋上默认值即可。


3、延伸

问题来源于自己写了configparser的扩展包,实现给get(),getint(),set()加默认值的方法,在python2中好用,移到python3中突然不好用了,有点发懵。

不过仔细分析,还是python3中configparser的get()有修改。

困扰了我接近一天,还是基本功有问题,贴上我写的简单代码。

补充一点:python3下默认有configparser,无需额外用pip安装,而且大写改成了小写。

#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 = rzhbook.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,u2222))
    
    #保存配置
    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()
    

 

以上是关于论python3下“多态”与“继承”中坑的主要内容,如果未能解决你的问题,请参考以下文章

Python3 与 C# 面向对象之~继承与多态

Python3-2020-测试开发-20- 面向对象之封装,继承,多态

java中封装,继承,多态,接口学习总结

Python类的继承与多态详细介绍

python3 多态,绑定方法与非绑定方法

java 代码片段