python中的继承与多态,dir()函数
Python继承
在继承关系中,已有的、设计好的类称为父类或基类,新设计的类称为子类或派生类。派生类可以继承父类的公有成员,但是不能继承其私有成员。如果需要在派生类中调用基类的方法,可以使用内置函数super()或者通过“基类名.方法名()”的方式来实现这一目的。
在Python中,如果一个类需要继承另一个类的成员,可以使用以下方式进行定义:
class BaseClass:def __init__(self):self.public_member = "I am a public member"self.__private_member = "I am a private member" # 双下划线开头的成员变量为私有成员def public_method(self):print("This is a public method")def __private_method(self):print("This is a private method")class DerivedClass(BaseClass):def derived_method(self):# 调用从父类继承的公共成员print(self.public_member)# 无法调用父类的私有成员# print(self.__private_member)# 调用从父类继承的公共方法self.public_method()# 通过super()函数调用父类的方法super().public_method()# 无法直接调用基类的私有方法# self.__private_method()
在以上代码中,BaseClass
是一个基类,DerivedClass
是一个派生类。在 BaseClass
中,定义了一个公有成员 public_member
和一个私有成员 __private_member
,以及一个公有方法 public_method
和一个私有方法 __private_method
。在 DerivedClass
中,继承了 BaseClass
的公有成员 public_member
和公有方法 public_method
,并且定义了一个派生类方法 derived_method
。
在派生类中,我们可以通过继承来使用从基类继承的公共成员和方法,但是无法直接调用基类中的私有成员或方法。如果需要在派生类中调用基类的方法,可以使用内置函数 super()
或者通过“基类名.方法名()
”的方式来实现这一目的。在 derived_method
中,我们展示了如何使用 super().public_method()
来调用基类的 public_method
方法。
Python支持多继承,如果父类中有相同的方法名,而在子类中使用时没有指定父类名,则Python解释器将从左向右按顺序进行搜索。
以下是一个简单的示例代码,用于说明Python支持多继承时的方法解析顺序(MRO)问题:
class A:def hello(self):print("Hello from A")class B:def hello(self):print("Hello from B")class C(A, B):passclass D(B, A):pass# 创建子类C的实例
obj_c = C()
obj_c.hello() # 输出 "Hello from A"# 创建子类D的实例
obj_d = D()
obj_d.hello() # 输出 "Hello from B"
在上面的示例代码中,我们定义了两个父类A
和B
,分别有相同的方法名hello
,同时我们分别创建了两个子类C
和D
,并使用多继承方式分别继承了A
和B
。
在子类C
中,我们没有定义hello
方法,因此当我们创建obj_c
实例后,调用hello
方法时,Python解释器按照继承顺序从左到右进行搜索,首先找到A
类中的hello
方法,并执行。
而在子类D
中,我们同样也没定义hello
方法,但我们将B
类放在A
类前面来继承,因此当我们创建obj_d
实例后,调用hello
方法时,Python解释器按照继承顺序从左到右进行搜索,首先找到B
类中的hello
方法,因此执行结果输出"Hello from B"。
这就是Python多继承时的方法解析顺序(MRO)问题,如果父类中有相同的方法名,而在子类中没有指定父类名,则Python解释器会按照子类继承父类的先后顺序从左到右进行搜索,找到第一个匹配的方法并执行。当然,我们也可以通过显式地指定父类名来调用指定的父类中的方法,避免方法名冲突问题。
在Python中,私有变量是可以继承的。但是,子类无法直接访问父类的私有属性,因为私有属性在父类实例化之后会被转成一个新的名称,子类中也无法访问这个名称。但如果需要子类能够访问父类的私有变量,可以通过调用父类的get和set方法来实现。
以下是一个简单的示例代码,用于说明在Python中,子类无法直接访问父类的私有属性,但可以通过调用父类的get和set方法来实现:
class Parent:def __init__(self):self.__private_var = "I am a private variable in parent class"def get_private_var(self):return self.__private_vardef set_private_var(self, value):self.__private_var = valueclass Child(Parent):def __init__(self):super().__init__()self.__private_var_in_child = "I am a private variable in child class"def print_private_var(self):# 子类无法直接访问父类的私有属性# print(self.__private_var) # 这里会出错# 如果需要访问父类的私有属性,可以通过调用父类的get方法来实现print(self.get_private_var())# 子类可以访问自己的私有属性print(self.__private_var_in_child)# 创建子类的实例
child_obj = Child()# 调用子类的方法来访问私有变量
child_obj.print_private_var()# 调用父类的方法来修改私有变量的值
child_obj.set_private_var("Modified private var in parent class")# 再次调用子类的方法来访问私有变量
child_obj.print_private_var()
运行上面的代码,输出结果如下:
I am a private variable in parent class
I am a private variable in child class
Modified private var in parent class
I am a private variable in child class
从输出结果可以看出,在子类中无法直接访问父类的私有变量__private_var
,但可以通过调用父类的公共方法get_private_var()
来获取私有变量的值,并且可以通过调用父类的公共方法set_private_var()
来修改私有变量的值。同时,子类也可以定义自己的私有变量,对于这些私有变量,则可以直接在子类中访问和修改。
dir()函数
dir()
函数是Python内置函数之一,它返回一个列表,包含当前作用域内的所有可用属性和方法的名称。它可以接受一个参数,表示要查询的对象或模块,也可以不传递参数,此时会返回当前作用域内的所有全局名称。
以下是一个示例:
class MyClass:def __init__(self):self.my_attribute = 42def my_method(self):passmy_object = MyClass()print(dir(my_object))
输出结果:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'my_attribute', 'my_method']
此处我们定义了一个 MyClass
类和一个 my_object
实例,并使用 dir()
函数来探索 my_object
的属性和方法。可以看到,除了我们在 MyClass
中定义的 "my_attribute"
和 "my_method"
之外,还有许多其他属性和方法在这个对象里面,例如 "__class__"
, "__dict__"
, "__doc__"
, "__hash__"
, 等等。
值得注意的是,这些以双下划线开头和结尾的名称都是对象所继承的一些特殊属性和方法,它们在Python中被称为“魔术方法”或“特殊方法”。它们在Python中有特殊的语法和行为,可用于实现一些特殊的功能,比如重载操作符。
另外,还有一些内置模块和函数也可以通过 dir()
函数进行探索。例如:
import mathprint(dir(math))
输出结果:
['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'nextafter', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc', 'ulp']
可以看到,在数学模块中,有许多不同的常量、函数和方法可供使用,例如符号常数 pi 或 tau,三角函数 sin 和 cos,还有一些数学运算和工具函数,例如 factorial 和 gcd 等,它们都可以通过 dir()
函数进行探索。
dir()
函数是一个十分强大的工具,它可以帮助我们快速了解和理解Python中可用的函数、模块、类、对象、方法等,并对我们在开发和调试代码时带来很多便利。
多态
在Python中,多态(polymorphism)是面向对象编程的一个重要概念,它指的是基类的同一方法在不同派生类对象中具有不同的表现和行为。也就是说,同样的方法名可以被派生类重写,从而实现不同的行为或逻辑。
下面我们来举一个简单的例子:
class Animal:def sound(self):print("The animal makes a sound.")class Dog(Animal):def sound(self):print("The dog barks.")class Cat(Animal):def sound(self):print("The cat meows.")def do_sound(animal):animal.sound()dog = Dog()
cat = Cat()do_sound(dog)
do_sound(cat)
在这个例子中,我们定义了一个基类 Animal
,它包含一个 sound()
方法,并打印出一条通用的动物发声信息。然后我们定义了两个派生类 Dog
和 Cat
,它们都继承了 Animal
的 sound()
方法,但改写了此方法以打印自己的声音信息。最后,我们编写了一个函数 do_sound()
,它接受一个 Animal
类型的参数,并调用它的 sound()
方法。
当我们创建一个实例 dog
或 cat
时,它们分别是 Dog
和 Cat
类型的对象,同时也都是 Animal
类型的对象。当我们调用 do_sound(dog)
或 do_sound(cat)
时,它们都会被传递给 do_sound()
函数,该函数会调用它们各自的 sound()
方法。由于派生类重写了基类方法,因此每个对象的 sound()
方法的行为都是不同的。
另外,需要注意的是,多态还可以用于参数和返回值的类型注解。例如:
from typing import Unionclass Shape:def area(self) -> float:passclass Rectangle(Shape):def __init__(self, width: float, height: float):self.width = widthself.height = heightdef area(self) -> float:return self.width * self.heightclass Circle(Shape):def __init__(self, radius: float):self.radius = radiusdef area(self) -> float:return 3.14 * self.radius ** 2def get_shape_area(shape: Union[Shape, Rectangle, Circle]) -> float:return shape.area()rectangle = Rectangle(5, 10)
circle = Circle(4)print(get_shape_area(rectangle))
print(get_shape_area(circle))
在这个例子中,我们定义了一个 Shape
基类,它包含一个 area()
方法,但没有实现任何具体逻辑。然后我们定义了两个派生类 Rectangle
和 Circle
,它们分别重写了 area()
方法以计算自己的面积。最后,我们编写了一个函数 get_shape_area()
,它接受一个 Shape
或其子类类型的参数,并调用它们的 area()
方法来获取它们的面积。
在这个例子中,我们使用了 Union
类型注解来指定函数参数的类型,表示它可以是 Shape
或其子类类型。这样,我们就可以在函数中以相同的方式处理不同类型的对象,并获得不同的结果。
需要注意的是,多态最大的好处之一是提高了代码的重用性和可扩展性。通过继承和多态,我们可以在不修改原有代码的情况下,轻松地添加新的行为和属性,或者修改现有的行为和属性,从而达到更好的代码复用和更好的系统扩展。
Python的运算符重载功能,是通过实现特殊方法(也称为魔术方法)来支持。这些特殊方法是以双下划线开头和结尾的,例如 __add__
是用来重载加法操作符 +
的。
在多态方面,Python中大多数运算符可以作用于多种不同类型的操作数,并且对于不同类型的操作数往往有不同的表现,这本身就是多态的体现。比如,在数字中,加号运算符用于执行加法操作,而在字符串中,加号运算符则用于字符串连接。
举个例子,我们定义一个自定义的类 Vector
,它代表二维向量,并希望支持向量的加法操作。为了支持加法操作符 +
,我们需要实现特殊方法 __add__
,并在其中定义加法操作的行为。
class Vector:def __init__(self, x, y):self.x = xself.y = y# 重载加法操作符def __add__(self, other):return Vector(self.x + other.x, self.y + other.y)
现在我们可以创建两个 Vector
对象,然后使用 +
运算符将它们相加:
v1 = Vector(2, 3)
v2 = Vector(4, 5)
v3 = v1 + v2
print(v3.x, v3.y) # 输出 6 8
此时我们可以看到,不同类型的操作数 v1
和 v2
都支持加法操作符,而且在 Vector
类中,加法的行为也是自定义的。这正是多态的体现。
除了上述例子中的加法操作符,Python还支持许多其他运算符的重载,例如减法、乘法、除法、位运算等等。在自定义类的操作中,运算符的重载让代码变得更具可读性和灵活性。
另外,在Python中,运算符重载也可以应用于内置的数据类型,比如数字、字符串、列表等,这使得开发者可以更自由地使用这些数据类型。
相关文章:

python中的继承与多态,dir()函数
Python继承 在继承关系中,已有的、设计好的类称为父类或基类,新设计的类称为子类或派生类。派生类可以继承父类的公有成员,但是不能继承其私有成员。如果需要在派生类中调用基类的方法,可以使用内置函数super()或者通过“基类名.…...

C++练级之初级:第五篇
C练级之初级:第五篇 第五篇 C练级之初级:第五篇1.auto关键字2.for循环改进3.指针空值nullptr4.内联函数4.1内联函数的概念4.2内联函数的注意点 总结 1.auto关键字 🤔什么是auto(automatic的缩写,自动的意思)关键字? au…...

JMeter的使用(二)
九、直连数据库 通过直连数据库让程序代替接口访问数据库,如果二者预期结果不一致,就找到了程序缺陷。 获取某条学院的名字,放在百度搜索: JMeter 不具备直连数据库功能,必须整合第三方(jar包)实现配置数据库的连接通过JDBC Re…...

C/C++文件操作/IO流
学习任务: ⭐认识文件。⭐学习C语言中文件如何打开和关闭。⭐学习C语言中文件的读写方法(包括顺序读写和随机读写)。⭐学习C语言文件操作中如何判断文件读取结束。⭐简单了解FILE缓冲区。⭐认识流。⭐学习C的IO流,包括标准IO流和文…...

推荐 7 个超牛的 Spring Cloud 实战项目
个 把一个大型的单个应用程序和服务拆分为数个甚至数十个的支持微服务,这就是微服务架构的架构概念,通过将功能分解到各个离散的服务中以实现对解决方案的解耦。 关于微服务相关的学习资料不多,而 GitHub 上的开源项目可以作为你微服务之旅…...

Linux信号:信号 信号集 信号集函数
1. 信号的概念 Linux进程间通信的方式之一。信号也称为“软件中断”。 信号特点: 简单;携带信息有限;满足特定条件才发送信号;可进行用户空间和内核空间进程的交互; 信号4要素: (1…...

详解八大排序算法-附动图和源码(插入,希尔,选择,堆排序,冒泡,快速,归并,计数)
目录 🍏一.排序的概念及应用🍏 1.排序的概念 2.排序的应用 3.常用的排序算法 🍎二.排序算法的实现🍎 1.插入排序 1.1直接插入排序 1.2希尔排序(缩小增量排序) 2.选择排序 2.1直接选择排序 2.2堆排序…...

网络编程--协议、协议族、地址族
写在前面 这里先介绍下socket函数(Windows版本)的函数声明,后续内容均围绕该声明展开: #include <winsock2.h> //af: 指定该套接字的协议族 //type: 指定该套接字的数据传输方式 //protocol: 指定该套接字的最终协议 //返…...

Linux入门操作
pwd 查看当前目录 与 自动补全 文件详情 drwxrwxr-x d代表文件夹 -代表文件 其中rwx rwx r-x r是可读 w是可写 x 执行 第一组(前三个)指文件拥有者的权限 第二组(中三个)代表文件拥有的组的权限 第三组(后三个&am…...

1。C语言基础知识回顾
学习嵌入式的C基础知识,主要包括几个核心知识点:三大语法结构、常用的数据类型、函数、结构体、指针、文件操作。 一、顺序结构 程序自上而下依次执行、没有分支、代码简单。 常见顺序结构有:四则运算:,-࿰…...

学习如何通过构建一个简单的JavaScript颜色游戏来操作DOM
学习如何通过构建一个简单的JavaScript颜色游戏来操作DOM 题目要求 我们将构建一个简单的颜色猜谜游戏。每次游戏启动时,都会选择一个随机的RGB颜色代码。根据游戏模式,我们将在屏幕上提供三个(简单)或六个(困难&…...

【算法学习】—n皇后问题(回溯法)
【算法学习】—n皇后问题(回溯法) 1. 什么是回溯法? 相信"迷宫"是许多人儿时的回忆,大家小时候一定都玩过迷宫游戏。我们从不用别人教,都知道走迷宫的策略是: 当遇到一个岔路口,会有以下两种情况…...

万亿OTA市场进入新爆发期,2025或迎中国汽车软件付费元年
伴随智能汽车市场规模发展,越来越多的汽车产品具备OTA能力,功能的优化、以及服务的差异化,成为了车企竞争的新战场。 例如,今年初,问界M5 EV迎来了首次OTA升级,升级内容覆盖用户在实际用车中的多个场景&am…...

Android硬件通信之 蓝牙Mesh通信
一,简介 蓝牙4.0以下称为传统蓝牙,4.0以上是低功耗蓝牙,5.0开始主打物联网 5.0协议蓝牙最重要的技术就是Mesh组网,实现1对多,多对多的无线通信。即从点对点传输发展为网络拓扑结构,主要领域如灯光控制等&…...

PG数据库实现bool自动转smallint的方式
删除函数: 语法: DROP FUNCTION IF EXISTS your_schema_name.function_name(arg_type1, arg_type2) CASCADE RESTRICT; 实例: DROP FUNCTION IF EXISTS platformyw.boolean_to_smallint(bool) CASCADE RESTRICT; 查询是否存在函数 语法: SELE…...

易观千帆 | 2023年3月证券APP月活跃用户规模盘点
易观:2023年3月证券服务应用活跃人数14131.58万人,相较上月,环比增长0.61%,同比增长0.60%;2023年3月自营类证券服务应用Top10 活跃人数6221.44万人,环比增长0.08%;2023年3月第三方证券服务应用T…...

2023年江苏专转本成绩查询步骤
2023年江苏专转本成绩查询时间 2023年江苏专转本成绩查询时间预计在5月初,参加考试的考生,可以关注考试院发布的消息。江苏专转本考生可在规定时间内在省教育考试院网,在查询中心页面中输入准考证号和身份证号进行查询,或者拨…...

JavaScript中sort()函数
sort()函数是javascript中自带函数,这个函数的功能是排序。 使用sort()函数时,函数参数如果不设置的话,以默认方式进行排序,就是以字母顺序进行排序,准确的讲就是按照字符编码的顺序进行排序。 var arr [3,2,3,34,1…...

泰克Tektronix DPO5204B混合信号示波器
特征 带宽:2 GHz输入通道:4采样率:1 或 2 个通道上为 5 GS/s、10 GS/s记录长度:所有 4 个通道 25M,50M:1 或 2 个通道上升时间:175 皮秒MultiView zoom™ 记录长度高达 250 兆点>250,000 wf…...

突破传统监测模式:业务状态监控HM的新思路
作者:京东保险 管顺利 一、传统监控系统的盲区,如何打造业务状态监控。 在系统架构设计中非常重要的一环是要做数据监控和数据最终一致性,关于一致性的补偿,已经由算法部的大佬总结过就不在赘述。这里主要讲如何去补偿ÿ…...

0Ω电阻在PCB板中的5大常见作用
在PCB板中,时常见到一些阻值为0Ω的电阻。我们都知道,在电路中,电阻的作用是阻碍电流,而0Ω电阻显然失去了这个作用。那它存在于PCB板中的原因是什么呢?今天我们一探究竟。 1、充当跳线 在电路中,0Ω电阻…...

分布式消息队列Kafka(三)- 服务节点Broker
1.Kafka Broker 工作流程 (1)zookeeper中存储的kafka信息 1)启动 Zookeeper 客户端。 [zrclasshadoop102 zookeeper-3.5.7]$ bin/zkCli.sh 2)通过 ls 命令可以查看 kafka 相关信息。 [zk: localhost:2181(CONNECTED) 2]…...

蠕动泵说明书_RDB
RDB_2T-S蠕 动 泵 概述 蠕动灌装泵是一种高性能、高质量的泵。采用先进的微处理技术及通讯方式做成的控制器和步进电机驱动器,配以诚合最新研制出的泵头,使产品在稳定性、先进性和性价比上达到一个新的高度。适用饮料、保健品、制药、精细化工等诸流量…...

浅谈react如何自定义hooks
react 自定义 hooks 简介 一句话:使用自定义hooks可以将某些组件逻辑提取到可重用的函数中。 自定义hooks是一个从use开始的调用其他hooks的Javascript函数。 下面以一个案例: 新闻发布操作,来简单说一下react 自定义 hooks。 不使用自定义hooks时 …...

如何优雅的写个try catch的方式!
软件开发过程中,不可避免的是需要处理各种异常,就我自己来说,至少有一半以上的时间都是在处理各种异常情况,所以代码中就会出现大量的try {...} catch {...} finally {...} 代码块,不仅有大量的冗余代码,而…...

海尔智家:智慧场景掌握「主动」权,用户体验才有话语权
2023年1月,《福布斯》AI专栏作家Rob Toews发布了年度AI发展预测,指出人工智能的发展将带来涉及各行业、跨学科领域的深远影响。变革将至,全球已掀起生成式AI热,以自然语言处理为代表的人工智能技术在快速进化,积极拥抱…...

基于铜锁,在前端对登录密码进行加密,实现隐私数据保密性
本文将基于 铜锁(tongsuo)开源基础密码库实现前端对用户登录密码的加密,从而实现前端隐私数据的保密性。 首先,铜锁密码库是一个提供现代密码学算法和安全通信协议的开源基础密码库,在中国商用密码算法,例…...

LVS的小总结
LVS的工作模式及其工作过程: LVS 有三种负载均衡的模式,分别是VS/NAT(nat 模式)、VS/DR(路由模式)、VS/TUN(隧道模式)。 1、NAT模式(NAT模式) 原理&#x…...

Spring依赖注入(DI配置)
Spring依赖注入 1. 依赖注入方式【重点】1.1 依赖注入的两种方式1.2 setter方式注入问题导入引用类型简单类型 1.3 构造方式注入问题导入引用类型简单类型参数适配【了解】 1.4 依赖注入方式选择 2. 依赖自动装配【理解】问题导入2.1 自动装配概念2.2 自动装配类型依赖自动装配…...

绘声绘影2023简体中文版新功能介绍
会声会影是一款专业的数字音频工作站软件,它提供强大的音频编辑和制作功能,被广泛应用于音乐创作、录音棚录制以及现场演出等领域。会声会影的最新版本会声会影2023将于2022年底发布,主要功能和新功能详述如下: 会声会影2023主要功能: 1. 直观易用的界面:会声会影采用简洁而不…...