当前位置: 首页 > news >正文

Python 之继承

概要

如果要修改现有类的行为,我们不必再从头建一个新的类,可以直接利用继承这一功能。下面将以实例相结合介绍继承的用法。
 


新建一个基类

代码如下:

class Marvel(object):    
    num_presents = 0 # 类变量,统计类实例中记录的作品数量
    def __init__(self, film_name, role):
        """
        file_name: 影名,字符串
        role: 影片角色,列表
        """
        self.film_name = film_name
        self.role = role
        Marvel.num_presents += 1
    def __del__(self):  # 调用 del 方法删除类实例时,作品数量同时-1
        Marvel.num_presents -= 1
    def add_role(self, name): 
        self.role.append(name)
    def reduce_role(self, name):
        self.role.remove(name)
    def inquiry(self, name):
        return name in self.role

上述代码中的类声明也可以省略写成 class Marvel:, 因为 object 是所有 Python 对象的根类。

其中 num_presents 是类变量,它是在类的所有实例之间共享的值。可以通过实例名或者类名 + . 的方式访问该变量值。在我们的实例中,该类变量是统计我们记录的漫威作品数量,每次声明一个作品时,该值就会自动增一,而且如果我们调用 del 方法删除作品时,会自动减一。示例如下:

a = Marvel('Revengers-1', ['Iron Man', 'Cap'])  # 创建一个类实例
print(a.num_presents) # 输出 1 等价于 Marvel.num_presents
b = Marvel('Revengers-2', ['Hulk', 'Cap'])   # 再创建一个类实例
print(a.num_presents) # 输出 2
del(a)
print(b.num_presents) # 输出 1

值得一提的是,如果你重复运行同样的程序(重复运行前内存中变量却没清除),小心输出的类变量值不一样。这就涉及了 python 的垃圾回收机制,简单地说,对于我们的实例,如果你对同样的变量名,比如 a,执行两次类实例声明操作,类变量的值 num_presents 不会变为 2,因为你再第二次赋值时,后台默认已经执行 del 方法回收了被覆盖掉的变量。

 

新建一个子类

class secondMarvel(Marvel):
    def __init__(self, film_name, role, score):
        Marvel.__init__(self, film_name, role)  # 等价于 super().__init__(film_name, role)
        self.score = score
    def add_role(self, name):
        if name in self.role:
            print("Warning: ", name, 'already exists in role !')
        super().add_role(name)  # python 3 , python 2 用 super(secondMarvel, self).add_role(name) 

在上述代码中,子类 secondMarvel 重新定义了 __init__ 函数,增加了一个属性 score(当然如果没必要增加属性,也就没必要重写该初始化函数)。而一旦重写了初始化函数,那么它不会自动调用基类的 __init__ 函数,所以我们要用显式地进行初始化声明(即 Marvel.__init__()),注意第一个参数是 self

另外我们改写了 add_role 方法,如果此时我们仍想调用基类中的方法实现,使用 super 方法即可。我们新写的方法只是打印出了警告而已。

 


总结

python 中的继承也支持多重继承,即一个子类可以同时有多个父类,此时如果继承的属性命名为惟一,搜索属性时会变得非常复杂,而实际应用中应该避免这种情况。本篇简单地介绍一下 python 中的继承机制以及了解其中一些实用技巧,在实际应用中可以多加尝试通过构建子类简化代码。
 

转载于:https://www.cnblogs.com/zhoukui/p/10802305.html

相关文章:

  • 写给我即将出生小孩的第一封信
  • Centos6.5安装Redis3.2.8
  • SSH connect issue 'exec request failed on channel 0'
  • SQL0668N Operation not allowed for reason code 3 on table TEST. SQLSTATE=57016
  • 作用域插槽slot
  • nodejs模块
  • 智能制造主战场在哪?数字化车间建设尤为重要
  • 快速排序(java实现)
  • 十天冲刺(6)
  • HashMap和HashTable的区别?HashTable和ConCurrentHashMap的区别?
  • 小笔记by项目遇到(整理)
  • 2019年5月9日考试解题报告
  • 银联基于OpenStack 的“五高”生产金融云技术白皮书
  • 通过shell终端上传下载文件
  • vscode——设置自动保存
  • “大数据应用场景”之隔壁老王(连载四)
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • Brief introduction of how to 'Call, Apply and Bind'
  • const let
  • co模块的前端实现
  • javascript 总结(常用工具类的封装)
  • JavaWeb(学习笔记二)
  • java小心机(3)| 浅析finalize()
  • Kibana配置logstash,报表一体化
  • Linux CTF 逆向入门
  • OSS Web直传 (文件图片)
  • select2 取值 遍历 设置默认值
  • Tornado学习笔记(1)
  • 彻底搞懂浏览器Event-loop
  • 仿天猫超市收藏抛物线动画工具库
  • 工作中总结前端开发流程--vue项目
  • 关于Flux,Vuex,Redux的思考
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 记录一下第一次使用npm
  • 聊聊flink的TableFactory
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 使用common-codec进行md5加密
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 一个SAP顾问在美国的这些年
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 正则表达式小结
  • 阿里云服务器购买完整流程
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (aiohttp-asyncio-FFmpeg-Docker-SRS)实现异步摄像头转码服务器
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (论文阅读40-45)图像描述1
  • (十五)使用Nexus创建Maven私服
  • (五)IO流之ByteArrayInput/OutputStream
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • (状压dp)uva 10817 Headmaster's Headache
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全