Python类与对象

目录

面向对象

定义类

创建对象

类的成员

实例变量

构造方法

实例方法

类变量

类方法

封装性

私有变量

私有方法

使用属性

继承性

Python中的继承

多继承

方法重写

多态性

继承与多态

鸭子类型测试与多态

面向对象

类和对象都是面向对象中的重要概念。面向对象是一种编程思想, 即按照真实世界的思维方式构建软件系统。

例如,在真实世界的校园里有学生和老师,学生有学号、姓名、所在班级等属性(数据),还有学习、提问、吃饭和走路等动作(方法) 。如果我们要开发一个校园管理系统,那么在构建软件系统时,也会有学生和老师等“类”,张同学、李同学是学生类的个体,被称为“对象”, “对象”也被称为“实例”。

定义类

Python中的数据类型都是类,我们可以自定义类,即创建一种新的数据类型。Python中类的定义语法格式如下所示。

class 类名[(父类)]: # 父类可以省略声明,表示直接继承object类#类体
class Car(object):pass # pass语句只能维持程序结构的完整。我们在编程时如果不想马上编写程序,又不想有语法错误,就可以使用pass语句

小汽车(Car)类继承了object类,object类是所有类的根类,在Python中任何一个类(除object外)都直接或间接地继承了object,直接继承object时(object)部分的代码可以省略。

创建对象

类相当于一个模板,依据这样的模板来创建对象,就是类的实例化 ,所以对象也被称为“实例”。

class Car(object):#类体pass
car=Car() # 创建一个小汽车对象小括号表示调用构造方法,构造方法用于初始化对象

对象不再使用时需要被销毁。在Python中销毁对象时由Python垃圾回收器在后台释放对象,不需要程序员手动释放对象。

类的成员

成员变量也被称为数据成员,保存了类或对象的数据。例如,学生的姓名和学号。 构造方法是一种特殊的函数,用于初始化类的成员变量。 成员方法是在类中定义的函数。 属性是对类进行封装而提供的特殊方法。 

注意:实例变量和实例方法属于对象,通过对象调用。而类变量和类方法属于类,通过类调用。

实例变量

实例变量就是对象个体特有的“数据”,例如狗狗的名称和年龄等。

class Dog:def __init__(self,name,age): # 构造方法,用来初始化实例变量self.name=name # 创建和初始化实例变量nameself.age=age # 创建和初始化实例变量age
d=Dog('球球',2) # 创建对象
print('我们家狗狗名叫{0},{1}岁了。'.format(d.name,d.age)) # 对实例变量通过“对象.实例变量”形式访问

类中的self表示当前对象,构造方法中的self参数说明这个方法属于实例,self.age中的self表示age属于实例,即实例成员变量

构造方法

类中的__init__()方法是一个非常特殊的方法,用来创建和初始化实例变量,这种方法就是“构造方法”。在定义__init__()方法时, 它的第1个参数应该是self,之后的参数用来初始化实例变量。调用构造方法时不需要传入self参数。

class Dog:def __init__(self,name,age,sex='雌性'): # 第一个参数必须是self,带有默认值的构造方法,能够给调用者提供多个不同版本的构造方法self.name=name # 创建和初始化实例变量nameself.age=age # 创建和初始化实例变量ageself.sex=sex # 创建和初始化实例变量sex
d1=Dog('球球',2) # 创建对象调用构造方法,省略默认值
d2=Dog('哈哈',1,'雌性')
d3=Dog(name='拖布',sex='雄性',age=3) # 使用关键字参数调用构造方法
print('{0}:{1}岁{2}。'.format(d1.name,d1.age,d1.sex))
print('{0}:{1}岁{2}。'.format(d2.name,d2.age,d2.sex))
print('{0}:{1}岁{2}。'.format(d3.name,d3.age,d3.sex))

输出结果

球球:2岁雌性。
哈哈:1岁雌性。
拖布:3岁雄性。

实例方法

实例方法与实例变量一样,都是某个实例(或对象)个体特有的方法。 定义实例方法时,它的第1个参数也应该是self,这会将当前实例与该方法绑定起来,这也说明该方法属于实例。在调用方法时不需要传入 self,类似于构造方法。

class Dog:# 构造方法def __init__(self,name,age,sex='雌性'):self.name=nameself.age=ageself.sex=sex# 实例方法def run(self): # 定义实例方法,只有一个self参数print('{}在跑...'.format(self.name))# 实例方法def speak(self,sound): # 定义实例方法,第一个参数是self,第二个参数是soundprint('{}在叫,"{}"!'.format(self.name,sound))
dog=Dog('球球',2)
dog.run() # 在调用时采用“对象.实例方法”形式,不需要传递参数
dog.speak('旺 旺 旺')

输出结果

球球在跑...
球球在叫,"旺 旺 旺"!

类变量

类变量是属于类的变量,不属于单个对象。 例如,有一个Account(银行账户)类,它有三个成员变量:amount(账户金额)、interest_rate (利率)和owner(账户名)。amount和owner对于每一个账户都是不同的,而interest_rate对于所有账户都是相同的。amount和owners是实例变量,interest_rate是所有账户实例共享的变量,它属于类,被称为“类变量”。

class Account:interest_rate=0.0568 # 类变量利率interest_ratedef __init__(self,owner,amount):self.owner=owner # 创建并初始化实例变量ownerself.amount=amount # 创建并初始化实例变量amount
account=Account('Tony',800000.0)
print('账户名:{0}'.format(account.owner)) # 对实例对象通过”对象.实例变量“形式访问
print('账户金额:{0}'.format(account.amount))
print('利率:{0}'.format(Account.interest_rate)) # 对类变量通过”类名.类变量“形式访问

类方法

类方法与类变量类似,属于类,不属于个体实例。在定义类方法时 ,它的第1个参数不是self,而是类本身。

class Account:interest_rate=0.068 #类变量利率def __init__(self,owner,amount):self.owner=owner # 定义实力变量self.amount=amount# 类方法@classmethod # 定义类方法需要的装饰器,装饰器以@开头修饰函数、方法和类,用来约束他们def interest_by(cls,amt): # cls代表类自身,即Account类return cls.interest_rate*amt # cls可以直接使用Account替换
interest=Account.interest_by(12000.0) # 对类方法可以通过”类名.类方法“形式访问
print('计算利息:{0:.4f}'.format(interest))

输出结果

计算利息:816.0000

注意:类方法可以访问类变量和其他类方法,但不能访问其他实例方法和实例变量。

封装性

封装性是面向对象重要的基本特性之一。封装隐藏了对象的内部细节,只保留有限的对外接口,外部调用者不用关心对象的内部细节,使得操作对象变得简单。

例如,一台计算机内部极其复杂,有主板、CPU、硬盘和内存等, 而一般人不需要了解它的内部细节。计算机制造商用机箱把计算机封装起来,对外提供了一些接口,如鼠标、键盘和显示器等,使用计算机就变得非常简单。

私有变量

为了防止外部调用者随意存取类的内部数据(成员变量),内部数据(成员变量)会被封装为“私有变量”。外部调用者只能通过方法调用私有变量。在默认情况下,Python中的变量是公有的,可以在类的外部访问它们。如果想让它们成为私有变量,则在变量前加上下画线(__)即可。

class Account:__interest_rate=0.0568 # 私有型变量def __init__(self,owner,amount):self.owner=ownerself.__amount=amountdef desc(self): # 在类的内部可以访问私有变量print("{0} 金额:{1} 利率:{2}。".format(self.owner,self.__amount,Account.__interest_rate))
account=Account('Tony',800000.0)
account.desc()print('账户名:{0}'.format(account.owner))
print('账户金额:{0}'.format(account.__amount)) # 错误发生
print('利率:{0}'.format(Account.__interest_rate)) # 错误发生,在类的外部不可以访问私有变量

私有方法

私有方法与私有变量的封装是类似的,在方法前加上下画线(__ )就是私有方法了。

class Account:__interest_rate=0.0568 # 私有型变量def __init__(self,owner,amount):self.owner=ownerself.__amount=amountdef __get_info(self):return "{0} 金额:{1} 利率:{2}。".format(self.owner,self.__amount,Account.__interest_rate)def desc(self): # 在类的内部可以访问私有变量print(self.__get_info()) # 在类的内部可以调用私有方法
account=Account('Tony',800000.0)
account.desc()
account.__get_info() # 发生错误,在类的外部调用私有方法,则发生错误

使用属性

为了实现对象的封装,在一个类中不应该有公有的成员变量,这些成员变量应该被设计为私有的,然后通过公有的set (赋值)和get(取值)方法访问。

使用set和get方法进行封装,示例代码如下:

class Dog:# 构造方法def __init__(self,name,age,sex='雌性'):self.name=nameself.__age=age# 实例方法def run(self):print("{}在跑...".format(self.name))# get方法,定义get()方法,返回私有实例变量__agedef get_age(self):return self.__age# set方法,定义set()方法,通过age参数更新私有实例变量__agedef set_age(self,age):self.__age=age
dog=Dog('球球',2)
print('狗狗年龄:{}'.format(dog.get_age())) # 通过get方法取值
dog.set_age(3) # 通过set方法赋值
print('修改后狗狗年龄:{}'.format(dog.get_age()))

输出结果

狗狗年龄:2
修改后狗狗年龄:3

在上面的示例中,当外部调用者通过两个公有方法访问被封装的私有成员变量时,会比较麻烦。所以我们可以在类中定义属性,属性可以替代get()和set()这两个公有方法,在调用时比较简单。

使用属性方式修改上面的示例,代码如下:

class Dog:# 构造方法def __init__(self,name,age,sex='雌性'):self.name=nameself.__age=age # 私有变量__age,对应的属性名应该去除前面双下画线之后的名称,即age# 实例方法def run(self):print("{}在跑...".format(self.name))@property # 定义age属性的get()方法,使用@property装饰器进行修饰,方法名就是属性名,即agedef age(self): # 替代get_age(self)return self.__age@age.setter # 定义age属性的set()方法,使用@age.setter装饰器进行修饰,age时属性名def age(self,age): # 替代set__age(self,age)self.__age=age
dog=Dog('球球',2)
print('狗狗年龄:{}'.format(dog.age())) # 可以通过属性取值,访问形式为”实例.属性“
dog.age(3) # 可以通过属性赋值,访问形式为”实例.属性“
print('修改后狗狗年龄:{}'.format(dog.age()))

属性在本质上就是两个方法,在方法前加上装饰器使得方法成为属性。属性使用起来类似于公有变量,可以在赋值符(=)左边或右边,左边被赋值,右边取值。

继承性

继承性也是面向对象重要的基本特性之一。 在现实世界中继承关系无处不在。例如猫与动物之间的关系:猫是一种特殊动物,具有动物的全部特征和行为,即数据和操作。在面向对象中动物是一般类,被称为“父类”;猫是特殊类,被称为“子类”。特殊类拥有一般类的全部数据和操作,可称之为子类继承父类。

Python中的继承

在Python中声明子类继承父类,语法很简单,定义类时在类的后面使用一对小括号指定它的父类就可以了。

class Animal: # 定义父类动物(Animal)def __init__(self,name):self.name=namedef show_info(self):return "动物的名字:{0}".format(self.name)def move(self):print("动一动...")
class Cat(Animal): # 定义子类猫(Cat)def __init__(self,name,age):super().__init__(name) # 调用父类构造方法,初始化父类成员变量self.age=age
cat=Cat('Tom',2)
cat.move()
print(cat.show_info())

输出结果

动一动...
动物的名字:Tom

注意:子类继承父类时,只有那些公有的成员变量和方法才可以被继承。

多继承

在Python中,当子类继承多个父类时,如果在多个父类中有相同的成员方法或成员变量,则子类优先继承左边父类中的成员方法或成员变量,从左到右继承级别从高到低。

class Horse:def __init__(self,name):self.name=namedef show_info(self):return "马的名字:{0}".format(self.name)def run(self):print("马跑...")
class Donkey:def __init__(self,name):self.name=namedef show_info(self):return "驴的名字:{0}".format(self.name)def run(self):print("驴跑...")def roll(self):print("驴打滚...")
class Mule(Horse,Donkey):def __init__(self,name,age):super().__init__(name)self.age=age
m=Mule('骡宝利',1)
m.run() # 继承父类Horse方法
m.roll() # 继承父类Donkey方法
print(m.show_info()) # 继承父类Horse方法

 输出结果

马跑...
驴打滚...
马的名字:骡宝利

方法重写

如果子类的方法名与父类的方法名相同,则在这种情况下,子类的方法会重写(Override)父类的同名方法。

class Horse:def __init__(self,name):self.name=namedef show_info(self):return "马的名字:{0}".format(self.name)def run(self):print("马跑...")
class Donkey:def __init__(self,name):self.name=namedef show_info(self):return "驴的名字:{0}".format(self.name)def run(self):print("驴跑...")def roll(self):print("驴打滚...")
class Mule(Horse,Donkey):def __init__(self,name,age):super().__init__(name)self.age=agedef show_info(self):return "骡:{0},{1}岁".format(self.name,self.age) # 重写父类方法show_info
m=Mule('骡宝利',1)
m.run() # 继承父类Horse方法
m.roll() # 继承父类Donkey方法
print(m.show_info()) # 子类Mule自己方法

输出结果

马跑...
驴打滚...
骡:骡宝利,1岁

多态性

多态性也是面向对象重要的基本特性之一。“多态”指对象可以表现出多种形态。 例如,猫、狗、鸭子都属于动物,它们有“叫”和“动”等行为,但是叫的方式不同,动的方式也不同。

继承与多态

在多个子类继承父类,并重写父类方法后,这些子类所创建的对象之间就是多态的。这些对象采用不同的方式实现父类方法。

class Animal:def speak(self):print('动物叫,但不知道是哪种动物叫')
class Dog(Animal):def speak(self):print('小狗:汪汪叫...')
class Cat(Animal):def speak(self):print('小猫:喵喵叫...')
an1=Dog()
an2=Cat()
an1.speak()
an2.speak()

输出结果

小狗:汪汪叫...
小猫:喵喵叫...

鸭子类型测试与多态

Python的多态性更加灵活,支持鸭子类型测试。鸭子类型测试指: 若看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟可以被称为鸭子。

由于支持鸭子类型测试,所以Python解释器不检查发生多态的对象是否继承了同一个父类,只要它们有相同的行为(方法),它们之间就是多态的。

例如,我们设计一个函数start(),它接收具有“叫”speak()方法的对象,代码如下:

def start(obj): # 接收的obj对象具有speak()方法obj.speak()

我们定义了几个类,它们都有speak()方法。代码如下:

class Animal:def speak(self):print('动物叫,但不知道是哪种动物叫')
class Dog(Animal):def speak(self):print('小狗:汪汪叫...')
class Cat(Animal):def speak(self):print('小猫:喵喵叫...')
class Car:def speak(self):print('小汽车:滴滴叫...')

start()函数可以接收所有speak()方法对象,代码如下:

start(Dog())
start(Cat())
start(Car())

输出结果

小狗:汪汪叫...
小猫:喵喵叫...
小汽车:滴滴叫...

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

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

相关文章

目标检测:3采用YOLOv8 API训练自己的模型

​ 目录 ​1.YOLOv8 的新特性 2.如何使用 YOLOv8? 3使用YOLOv8训练模型 4.验证训练集 5.测试训练集 6.测验其他图片 7 其他问题 参考: 1.YOLOv8 的新特性 Ultralytics 为 YOLO 模型发布了一个全新的存储库。它被构建为 用于训练对象检测、实例分割和图像分类模型的统…

【JS逆向学习】今日头条

逆向目标 目标网页:https://www.toutiao.com/?wid1707099375036目标接口:https://www.toutiao.com/api/pc/list/feed目标参数:_signature 逆向过程 老规矩先观察网络请求,过滤XHR请求观察加密参数,发现Payload的_s…

arm 汇编积累

C语言函数与汇编对应关系 一、MOV 系列指令 1、指令格式 MOV{条件}{S} 目的寄存器,源操作数 2、含义解析: (1):mov 指令传送数据 案例: MOV R0,R1 ; R0 R1; MOV PC,R14 ;PC R14; MOV R0,R…

Kafka SASL_SSL双重认证

文章目录 1. 背景2. 环境3. 操作步骤3.1 生成SSL证书3.2 配置zookeeper认证3.3 配置kafka安全认证3.4 使用kafka客户端进行验证3.5 使用Java端代码进行认证 1. 背景 kafka提供了多种安全认证机制,主要分为SASL和SSL两大类。 SASL: 是一种身份验证机制&…

【机器学习与自然语言处理】预训练 Pre-Training 各种经典方法的概念汇总

【NLP概念合集:一】预训练 Pre-Training,微调 Fine-Tuning 及其方法的概念区别 前言请看此正文预训练 Pre-Training无监督学习 unsupervised learning概念:标签PCA 主成分分析(Principal Component Analysis)降维算法L…

本地部署TeamCity打包发布GitLab管理的.NET Framework 4.5.2的web项目

本地部署TeamCity 本地部署TeamCity打包发布GitLab管理的.NET Framework 4.5.2的web项目部署环境配置 TeamCity 服务器 URLTeamCity 上 GitLab 的相关配置GitLab 链接配置SSH 配置项目构建配置创建项目配置构建步骤构建触发器结语本地部署TeamCity打包发布GitLab管理的.NET Fra…

市场复盘总结 20240205

仅用于记录当天的市场情况,用于统计交易策略的适用情况,以便程序回测 短线核心:不参与任何级别的调整,采用龙空龙模式 一支股票 10%的时候可以操作, 90%的时间适合空仓等待 二进三: 进级率低 50% 最常用…

Leetcode刷题笔记题解(C++):257. 二叉树的所有路径

思路:深度优先搜索 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right…

[软件工具]文档页数统计工具软件pdf统计页数word统计页数ppt统计页数图文打印店快速报价工具

文档页数统计工具软件——打印方面好帮手 在信息化时代,文档已成为我们工作、学习、生活中不可或缺的一部分。无论是学术论文、商业报告,还是个人日记,都需要我们对其进行有效的管理。而在这个过程中,文档页数统计工具软件就显得…

掌握CSS网格函数fit-content()的妙用

CSS网格布局是一种强大的布局系统,它提供了灵活的网格化设计能力。其中,fit-content()函数是一项重要的功能,它可以帮助我们在网格容器中自动调整网格项的尺寸。本文将详细讲解fit-content()函数的使用方法及其常见应用场景,助你掌…

ETL是什么,有哪些ETL工具?就业前景如何?

ETL是什么 ETL(Extract-Transform-Load),用来描述将数据从来源端经过抽取(extract)、转换(transform)、加载(load)至目标端的过程。ETL一词较常用在数据仓库,但其对象并不限于数据仓库。它可以自动化数据处理过程,减少…

2023_中国零售业人工智能行业应用 发展图谱

01 零售人工智能行业应用发展背景 02 零售人工智能行业应用发展图谱及行业应用案例 案例:京东云、蓝色光标、京东言犀智能服务、腾讯企点、 案例:淘天集团、极睿科技、百度电商数字人直播 案例:中国联通、云拿科技AI智能商店; 0…

【flutter】报错 cmdline-tools component is missing

在flutterSDK目录下,双击flutter_console.bat,调出命令行。 输入flutter doctor,如果第三个诊断为[x],报cmdline-tools component is missing错(我这已经修改好了,所以是勾了),那就可…

HTTP和HTTPS区别!

http 是我们几乎天天都要打交道的东西,相关知识点有点多,所以也有不少面试必问的点,这里做了一些整理,帮且大家树立完整的 http 知识体系,对面试官说 so easy HTTP 的特点和缺点 特点:无连接、无状态、灵…

运行vue3项目出现的问题

Mac 系统运行 vue 启动项目时报错: Permission denied 的解决方式 控制台运行 chmod 777 node_modules/.bin/vue-cli-service 如果 npm run dev 还报这个错 控制台运行 node node_modules/esbuild/install.js

day44_jdbc

今日内容 0 复习昨日 1 讲作业 2 数据库连接池(druid) 3 反射 4 改造DBUtil 5 完成CRUD练习 0 复习昨日 1 sql注入 2 预处理语句 3 事务操作 4 DBUtil 1 作业【重要】 利用ORM完成,以下的几个方法非常重要,将来写项目就是这些操作 写项目步骤 搭建环境 创建项目导入依赖工具类数…

Oracle笔记-为表空间新增磁盘(ORA-01691)

如下报错: 原因是Oracle表空间满了,最好是新增一个存储盘。 #查XXX命名空间目前占用了多大的空间 select FILE_NAME,BYTES/1024/1024 from dba_data_files where tablespace_name XXXX #这里的FILE_NAME能查到DBF的存储位置#将对应的datafile设置为30g…

ffmpeg命令生成器

FFmpeg 快速入门:命令行详解、工具、教程、电子书 – 码中人的博客FFmpeg 是一个强大的命令行工具,可以用来处理音频、视频、字幕等多媒体文件。本文介绍了 FFmpeg 的基本用法、一些常用的命令行参数,以及常用的可视化工具。https://blog.mzh…

Golang与Erlang有什么差异

Golang和Erlang是两种备受关注的编程语言,它们各自具有独特的特点和优势。下面我将简单的探讨一下Golang和Erlang之间的差异,并且分析它们在并发模型、运行环境、函数式编程和领域特性等多个方面的不同之处。 并发模型 Golang使用goroutines和channels…

Java设计模式大全:23种常见的设计模式详解(二)

本系列文章简介: 设计模式是在软件开发过程中,经过实践和总结得到的一套解决特定问题的可复用的模板。它是一种在特定情境中经过验证的经验和技巧的集合,可以帮助开发人员设计出高效、可维护、可扩展和可复用的软件系统。设计模式提供了一种在…