python类继承之__init__函数覆盖问题

news2025/1/12 6:20:02

目录

1.问题描述

2.代码演示

3.总结


在Python这个广受欢迎的编程语言中,类继承是一项强大而精巧的特性。通过类继承,我们可以构建出更加灵活、可重用和易维护的代码,同时实现代码的模块化和扩展性。

但是如果对于熟悉C++和java的人而言,首次接触python的类继承,可能会因__init__函数同名覆盖问题而困惑。下面将详细介绍该问题。

1.问题描述

python中__init__函数可以类比为C++中的构造函数,都是对成员变量进行初始化。当创建子类对象的时候,默认情况下,C++中会先调用父类的默认构造函数,在调用子类的默认构造函数。而在python由于初始化函数都是__init__,那么创建子类对象的时候,存在同名函数问题,那会默认调用父类的__init__函数嘛?如果没有调用会发生什么情况?应该怎么解决呢?

2.代码演示

python中创建子类,__init__函数的调用可以分为三种情况来验证:
(1)子类重写了__init__函数,显式调用父类__init__

(2)子类重写__init__函数,未显式调用父类__init__

(3)子类未重写__init__函数,未显式调用父类__init__

class CBase:
    def __init__(self) -> None:
        print("this is Base init")
        self.test_str="Base"
        self.test_str2="Base2"
        
​
​
class CSub1(CBase):
    def __init__(self) -> None:
        super().__init__()
​
​
class CSub2(CBase):
    def __init__(self) -> None:
        print("this is sub2 init")
​
class CSub3(CBase):
    def test_sub3_func(self):
        print("this is test_sub3_func")
​
if __name__=="__main__":
    t1=CSub1()
    t2=CSub2()
    t3=CSub3()

执行结果

根据执行结果,我们可以得出以下结论:
子类如果重写了__init__函数,父类__init__函数需要显式调用才会执行

子类如果没有重写__init__函数,父类__init__函数隐式调用。

这种行为是由Python的继承机制所决定的。当一个类继承另一个类时,子类继承了父类的属性和方法。但是,如果子类重写了父类的方法,并且在重写的方法中没有显式调用父类的相应方法,那么父类的方法将不会被执行。

那么接下来,如果子类重写__init__函数,但又没有显式调用父类__init__函数,会发生什么情况,如下代码,我们试图在派生类中打印基类的成员变量test_str​:

class CBase:
    def __init__(self) -> None:
        print("this is Base init")
        self.test_str="Base"
        self.test_str2="Base2"
    
class CSub2(CBase):
    def __init__(self) -> None:
        print("this is sub2 init")
        print(self.test_str)

执行结果:

可以看到结果报错了,子类中没有这个​成员变量。

根据执行结果,在父类__init__函数中创建的类属性,子类都无法访问。这一点和C++中有所不同。在C++中,考虑public权限和public继承的情况下,子类一定可以访问到父类的成员变量。

这是因为,在C++这样的静态语言中,创建对象时,成员变量会在对象创建时一同创建。在定义类时,编译器会根据类的定义为每个对象分配内存,并初始化成员变量。

​而在Python这样的动态语言中,对象的属性并不在创建对象时就创建。相反,Python的对象是在运行时动态创建的,并且可以在任何时候添加、修改或删除对象的属性。

而在继承的过程中,子类重写了__init__函数,导致父类的__init__函数没有执行,因此,父类__init__函数中的属性并没有创建,子类访问时必然出错。这一点可以推广到子类和父类的同名函数中。

3.总结

Python是动态语言,其类继承有两个特点:

  • 如果派生类和基类中存在同名函数,派生类的函数会覆盖基类函数,即使是构造函数__init__也不例外。因此,如果要调用基类的同名函数,需要使用super显式调用​。

  • Python是动态语言,类的成员变量是允许动态创建的,因此,当创建派生类对象时,会创建基类对象,但不会为基类对象创建成员变量,此时派生类直接访问基类的成员变量会报错

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1399878.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flink实战之运行架构

本文章:重点是分析清楚运行架构以及并行度与slot的分配 1、JobManager和TaskManager Flink中的节点可以分为JobManager和TaskManager。 JobManager处理器也称为Master,用于协调分布式任务执行。他们用来调度task进行具体的任务。TaskManager处理器也称…

蓝桥杯真题(Python)每日练Day2

题目 题目分析 对于本题首先确定其数据结构为优先队列,即邮费最小的衣服优先寄,算法符合贪心算法。可以直接使用queue库的PriorityQueue方法实现优先队列。关于PriorityQueue的使用方法主要有: import queue q queue.Queue()# 队列 pq qu…

【JavaEE】文件操作 —— IO

文件操作 —— IO 1. 文件的属性 文件内容文件大小文件路径文件名称 2. 文件的管理 采用树形结构进行管理。 3. 文件路径 分为两种:相对、绝对路径。 相对路径:相对于当前位置的路径,以“./xxx.xxx”为标志绝对路径:以从盘符…

【工具使用-win10最近使用的文件】怎样关闭win10系统最近使用的文件功能

一,简介 有时候我们不想打开文件管理器的时候,就出现之前访问过的文件或者文件夹,本文就介绍在win10系统下如何关闭“最近使用文件”的功能。 二,操作步骤 打开资源管理器,点击“选项” 按照如下步骤操作&#xff…

树结构实战,获取文件夹大小

文件IO是一个耗时操作,要尽量避免频繁读取磁盘。 而我们需要分析磁盘的占用空间,无法避免需要读取,但是期望只通过一次文件IO操作,来获取到所有某个目录下所有文件夹的信息。 所以需要一种方式可以仅进行一轮磁盘操作&#xff0…

【Linux】安装n卡驱动以及可能遇到的问题

文章目录 1.换源以及更新2.安装依赖3. 安装n卡驱动独显与核显切换nvidia-settings消失忘记安装依赖无法进入图形化界面的急救命令行无响应办法 1.换源以及更新 目前,换源完全只需要鼠标点点点就可以完成了,打开应用列表里的Software & Updates&…

vue3-模版引用

模版引用 ref 属性 场景&#xff1a;需要直接访问底层 DOM 元素。 方法&#xff1a;使用特殊的 ref 属性。 <input ref"input">ref 属性 允许我们在一个特定的 DOM 元素或子组件实例被挂载后&#xff0c;获得对它的直接引用。 访问模板引用 小 Demo: 当 i…

rk1126, 实现 yolov8 目标检测

基于 RKNN 1126 实现 yolov8 目标检测 Ⓜ️ RKNN 模型转换 ONNX yolo export model./weights/yolov8s.pt formatonnx导出 RKNN 这里选择输出 concat 输入两个节点 onnx::Concat_425 和 onnx::Concat_426 from rknn.api import RKNNONNX_MODEL ./weights/yolov8s.onnxRKNN_MOD…

flink operator 拉取阿里云私有镜像(其他私有类似)

创建 k8s secret kubectl --namespace flink create secret docker-registry aliyun-docker-registry --docker-serverregistry.cn-shenzhen.aliyuncs.com --docker-usernameops_acr1060896234 --docker-passwordpasswd --docker-emailDOCKER_EMAIL注意命名空间指定你使用的 我…

使用 vsCode创建GO项目

最近回顾了一下go的使用&#xff1a;具体操作看下面的参考连接&#xff0c;下面只描述一些踩过的坑&#xff1a; 1. go安装配置 安装go->配置go环境变量 推荐官网下载&#xff0c;速度很快&#xff1b; 这里需要配置五个参数&#xff1a;GOPATH/GOROOT/Path、GO111MODULE/…

GitHub提交 / 拉取时 443 fatal: unable to access ‘https:

这个问题嘛 懂得都懂 但是用了魔法后依旧会出现443错误 排查了工具发现并不是工具的问题 修改一下git代理即可解决 解决方法如下 确保魔法可用的情况下 打开魔法 打开系统设置 > 网络和Internet > 代理 找到自己的代理IP 如下 这里以我的代理IP和端口举例 在…

【工具】使用ssh进行socket5代理

文章目录 shellssh命令详解正向代理&#xff1a;反向代理&#xff1a;本地 socks5 代理 shell ssh -D 3333 root192.168.0.11 #输入密码 #3333端口已经使用远程机进行转发设置Windows全局代理转发 socks127.0.0.1 3333如果远程机为公网ip&#xff0c;可通过搜索引擎查询出网…

【C语言】数据在内存中的存储知识点(1)

一、整数在内存中的存储 二、大小端字节序和字节序判断 三、浮点数在内存中的存储

Linux的IO文件操作和文件系统

前要&#xff1a;本次我想给您带来关于 IO 和文件的知识&#xff0c;而文件在本系列中分为内存上的文件和磁盘上的文件。 1.文件概念 1.1.文件读写 在谈及系统接口之前&#xff0c;我们先来从 C 语言的角度来谈及一些前要知识&#xff0c;以辅助我们后续来理解系统 IO。 我们…

burp靶场--文件上传

burp靶场–文件上传 https://portswigger.net/web-security/file-upload/lab-file-upload-remote-code-execution-via-web-shell-upload 1.文件上传 1、原理&#xff1a;文件上传漏洞是指Web服务器允许用户将文件上传到其文件系统&#xff0c;而不充分验证文件的名称、类型、…

Shell 脚本实现自动启动程序、日志管理和定时任务监控

简介 本篇将通过Shell 脚本实现自动启动Java程序、日志管理和定时任务监控。脚本启动程序具灵活定制、可移植性和扩展性强的优点&#xff0c;可以根据需要添加额外的功能、配置选项和自定义行为&#xff0c;从而满足更具体的要求。 脚本编写 vim start_program.sh#!/bin/bas…

Lambda支持的方法引用

目录 引用类中的静态方法替换lambda引用对象实例化方法替换lambda引用类中的实例方法替换lambda引用构造器替换lambda 引用类中的静态方法替换lambda 引用类方法&#xff1a;引用类的静态方法&#xff1b;类名::静态方法名 demo: 将String类型数据转换成为Integer类型 创建一个…

MySQL 8.3 发布, 它带来哪些新变化?

1月16号 MySQL 官方发布 8.3 创新版 和 8.0.36 长期支持版本 (该版本 没有新增功能&#xff0c;更多是修复bug )&#xff0c;本文基于 官方文档 说一下 8.3 版本带来的变化。 一 增加的特性 1.1 GTID_NEXT 支持增加 TAG 选项。 之前的版本中 GTID_NEXTUUID:number &#xff…

Ant下载及安装

文章目录 前言一、Ant下载二、Ant安装三、Ant配置环境变量 前言 Ant是一个帮助构建软件的Java库和命令行工具。Ant是一个Java库和命令行工具&#xff0c;其任务是将构建文件中描述的过程驱动为相互依赖的目标和扩展点。Ant的主要已知用途是构建Java应用程序。Ant提供了许多内置…

DolphinScheduler-3.2.0集群部署教程

本文目录 1.集群部署方案(2 Master 3 Worker)2.前置准备工作3.端口说明4.DS集群部署1.时间同步2.配置用户、权限3.配置集群免密登陆4.ZK集群启动5.初始化数据库1.创建数据库、用户、授权2.解压缩安装包3.添加MySQL驱动至libs目录 6.配置文件修改1.dolphinscheduler_env.sh 配置…