当前位置:

首页 > 编程开发 > Python中如何使用类和对象?

Python中如何使用类和对象?

对象=属性+方法我们前面其实已经接触过封装的概念,把乱七八糟的数据扔进列表里面,这是一种封装,是数据层面的封装;把常用的代码段打包成一个函数,这也是一种封装,是语句层面的封装;现在我们要学习的对象,也是一种封装的思想,对象的来源是模拟真是世界,将数据和代码都封装在了一起。打个比方,乌龟就是真实世界的一个对象,通常会从两个部分来描述它。(1)从静态的特征描述:例如,绿色的,有四条腿,有外壳等等,这是静态一方面的描述。(2)从动态的行为描述:例如,它会爬,如果追它,它还会跑,有时还会咬人,睡觉等等,这都是从行

对象 = 属性 + 方法

我们前面其实已经接触过封装的概念,把乱七八糟的数据扔进列表里面,这是一种封装,是数据层面的封装;把常用的代码段打包成一个函数,这也是一种封装,是语句层面的封装;现在我们要学习的对象,也是一种封装的思想, 对象的来源是模拟真是世界,将数据和代码都封装在了一起。

打个比方,乌龟就是真实世界的一个对象,通常会从两个部分来描述它。
(1)从静态的特征描述:例如,绿色的,有四条腿,有外壳等等,这是静态一方面的描述。
(2)从动态的行为描述:例如,它会爬,如果追它,它还会跑,有时还会咬人,睡觉等等,这都是从行为方面进行描述的。

Python中的对象也是如此,一个对象的特征称为“属性”一个对象的行为称为“方法”。:

如果将乌龟写成代码,将会是下面这样:

class Turtle: # Python中的类名约定以大写字母开头
    
    # 特征的描述称为属性,在代码层面看来其实就是变量
    color = 'green'
    legs = 4
    shell = True

    # 方法实际就是函数,通过调用这些函数来完成某些工作
    def climb(self):
        print('向前爬')
    def run(self):
        print('向前跑')
    def bite(self):
        print('咬人')
    def sleep(self):
        print('睡觉')

以上代码定义了对象的特征(属性)和行为(方法),但还不是一个完整的对象,将定义的这些称为类(Class)。需要使用类来创建一个真正的对象,这个对象就叫作这个类的一个实例(Instance),也叫实例对象(Instance Objects)
举个例子,这就像工厂需要生产一系列玩具,需要先作出这个玩具的模具,然后根据这个模具再进行批量生产。

那么怎么创建真正的实例对象呢?创建一个对象,也叫类的实例化其实很简单:

# 首先要有上面那一段类的定义
tt = Turtle()

注意:类名后面跟着小括号,这跟调用函数是一样的。所以在Python中,类名约定用大写字母开头,函数用小写字母开头,这样更容易区分。另外,赋值操作并不是必需的,但如果没有把创建好的实例对象赋值给一个变量,这个对象就没办法使用,因为没有引用指向这个实例,最终会被Python的垃圾回收机制自动回收。

如果要 调用对象里的方法,使用点操作符(.) 即可。

Python中如何使用类和对象?


 

接下来我们看一段代码,再深入理解一下类对象实例对象三个概念:

Python中如何使用类和对象?

从这个例子可以看出,对实例对象c的count属性进行赋值后,就相当于覆盖了类对象C的count属性。如下图所示,如果没有赋值覆盖,那么引用的是类对象的count属性。

Python中如何使用类和对象?

需要注意的是,类中定义的属性是静态变量,类的属性是与类对象进行绑定,并不会依赖任何它的实例对象。

另外,如果属性的名字跟方法名相同,属性会覆盖方法

Python中如何使用类和对象?

为了避免名字上的冲突,应该遵守一些约定俗成的规矩:
(1)不要试图在一个类里面定义出所有能想到的特性和方法,应该利用继承和组合机制进行扩展。
(2)用不同的词性命名,如属性名用名词、方法名用动词,并使用驼峰命名法等。

self是什么

细心的读者发现对象的方法都会有一个self参数,那么这个self是什么呢?如果你接触过C++,那么你应该很容易对号入座,Python的self其实就相当于C++的this指针

如果你此前没有接触过任何编程语言,那么简单说,如果把类比作图纸,那么由类实例化后的对象才是真正可以住的房子。根据一张图纸可以设计出成千上万的房子,它们外观都差不多,但是每一个房子都有不同的主人。每个人要找到自己的房子,那self就相当于这里的门牌号,有了self,你就可以轻松找到自己的房子。

Python的self参数就是同一个道理,由一个类可以生成无数个对象,当一个对象方法被调用的时候,对象会将自身的引用作为第一个参数传给该方法,那么Python就知道需要操作哪个对象的方法了

举个简单的例子:

Python中如何使用类和对象?

公有和私有

一般面向对象的编程语言都会区分公有和私有的数据类型,像C++和Java它们使用public和private关键字用于声明数据是公有的还是私有的,但在Python中并没有类似的关键字来修饰。

默认上对象的属性和方法都是公开的,可以直接通过点操作符(.)进行访问

Python中如何使用类和对象?

为了实现类似私有变量的特征,Python内部采用了一种叫name mangling(名字改编)的技术,在Python中定义私有变量只需要在变量名或函数名前加上“_ _”两个下划线,那么这个函数或变量就会成为私有的了

Python中如何使用类和对象?

这样,在外部将变量名“隐藏”起来了,理论上如果要访问,就要从内部进行

Python中如何使用类和对象?

但是认真想一下这个技术的名字name mangling(名字改编),那就不难发现其实Python只是把双下横线开头的变量进行了改名而已。实际上,在外部使用“_类名_ _变量名”即可访问双下横线开头的私有变量了

Python中如何使用类和对象?

说明:Python目前的私有机制其实是伪私有的,Python的类是没有权限控制的,所有的变量都是可以被外部调用的

继承

举个例子来说明继承。例如现在有个游戏,需要对鱼类进行细分,有金鱼(Goldfish)、鲤鱼(Carp)、三文鱼(Salmon)以及鲨鱼(Shark)。那么我们能不能不要每次都从头到尾去重新定义一个新的鱼类呢?因为我们知道大多数鱼的属性和方法是相似的,如果有一种机制可以让这些相似的东西得以自动传递,那么就方便多了。这就是继承。

继承的语法很简单:

c l a s s 类 名 ( 被 继 承 的 类 ) : . . . class 类名(被继承的类): \\ \quad ... class类名(被继承的类):...

被继承的类称为基类、父类或超类;继承者称为子类,一个子类可以继承它的父类的任何属性和方法。

举个例子:

Python中如何使用类和对象?

需要注意的是,如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性

Python中如何使用类和对象?

接下来,尝试写一下开头提到的金鱼(Goldfish)、鲤鱼(Carp)、三文鱼(Salmon)以及鲨鱼(Shark)的例子。

import random as r
class Fish:
    def __init__(self):
        self.x = r.randint(0, 10)
        self.y = r.randint(0, 10)
    def move(self):
        # 这里主要演示类的继承机制,就不考虑检查场景边界和移动方向问题
        # 假设所有的鱼都是一路向西游
        self.x -= 1
        print("我的位置是:", self.x, self.y)
# 金鱼
class Goldfish(Fish):
    pass
# 鲤鱼
class Carp(Fish):
    pass
#三文鱼
class Salmon(Fish):
    pass
# 上面三种鱼都是食物,直接继承Fish类的全部属性和方法
# 下面定义鲨鱼类,除了继承Fish类的属性和方法,还要添加一个吃的方法
class Shark(Fish):
    def __init__(self):
        self.hungry = True
    def eat(self):
        if self.hungry:
            print("吃掉你!")
            self.hungry = False
        else:
            print("太饱了,吃不下了~")

首先运行这段代码,然后进行测试:

Python中如何使用类和对象?

同样是继承于Fish类,为什么金鱼(goldfish)可以移动,而鲨鱼(shark)一移动就报错呢?
可以看到报错提示为:Shark对象没有x属性,这是因为在Shark类中,重写了_ _init_ _()方法,但新的_ _init_ _()方法里面没有初始化鲨鱼的x坐标和y坐标,因此调用move()方法就会出错。
那么解决这个问题,只要在鲨鱼类中重写_ _init_ _()方法的时候先调用基类Fish的_ _init_ _()方法

下面介绍两种可以实现的技术:

  • (1)调用未绑定的父类方法

  • (2)使用super函数

调用未绑定的父类方法

什么是调用未绑定的父类方法?举个例子:

Python中如何使用类和对象?

修改之后,再运行下发现鲨鱼也可以成功移动了:

Python中如何使用类和对象?

这里需要注意的是,这个self并不是父类Fish的实例对象,而是子类Shark的实例对象。所以这里说的未绑定是指并不需要绑定父类的实例对象,使用子类的实例对象代替即可。

使用super函数

super函数能够帮助我们自动找到基类的方法,而且还为我们传入了self参数,这样就不需要做这些事情了:

Python中如何使用类和对象?

运行后得到同样的结果:

Python中如何使用类和对象?

多重继承

除此之外,Python还支持多重继承,就是可以同时继承多个父类的属性和方法

c l a s s 类 名 ( 父 类 1 , 父 类 2 , 父 类 3 , . . . ) : . . . class 类名(父类1,父类2,父类3,...):\\ \quad ... class类名(父类1,父类2,父类3,...):...

举个例子:

Python中如何使用类和对象?

这就是基本的多重继承语法,但多重继承很容易导致代码混乱,所以当你不确定是否真的必须使用多重继承的时候,请尽量避免使用它,因为有些时候会出现不可预见的BUG。

组合

前面学习了继承的概念,又提到了多重继承,但如果现在我们有了乌龟类、鱼类,现在要求定义一个类,叫水池,水池里要有乌龟和鱼。用多重继承就显得很奇怪,因为水池和乌龟、鱼是不同物种,那怎样把它们组合成一个水池的类呢?
其实在Python中很简单,直接把需要的类放进去实例化就可以了,这就叫组合

Python中如何使用类和对象?

先运行上段代码,然后测试:

Python中如何使用类和对象?

构造和析构

Python的对象有许多神奇的方法,如果你的对象实现了这些方法中的某一个,那么这个方法就会在特殊情况下被Python所调用,而这一切都是自动发生的。

_ _init_ _(self[, …])构造方法

通常把_ _init_ _()方法称为构造方法,只要实例化一个对象,这个方法就会在对象被创建时自动调用。实例化对象时是可以传入参数的,这些参数会自动传入_ _init_ _()方法中,可以通过重写这个方法来自定义对象的初始化操作

举个例子:

Python中如何使用类和对象?

有些读者可能会问,有些时候在类定义时写_ _init_ _()方法,有时候却没有,这是为什么呢?看下面这个例子:

Python中如何使用类和对象?

这里需要注意的是,_ _init_ _()方法的返回值一定是None,不能是其他

Python中如何使用类和对象?

所以,一般在需要进行初始化的时候才重写_ _init_ _()方法。所以这个_ _init_ _()方法并不是实例化对象时第一个被调用的方法

_ _new_ _(cls[, …])方法

_ _new_ _()方法才是一个对象实例化的时候所调用的第一个方法。与其他方法不同的是,它的第一个参数不是self而是这个类(cls),而其他的参数会直接传递给_ _init_ _()方法的。

_ _new_ _()方法需要返回一个实例对象,通常是cls这个类实例化的对象,当然你也可以返回其他对象。

_ _new_ _()方法平时很少去重写它,一般让Python用默认的方案执行即可。但是有一种情况需要重写这个方法,就是当继承一个不可变的类型的时候,它的特性就显得尤为重要了。

Python中如何使用类和对象?

_ _del_ _(self)析构方法

如果说_ _init_ _()和_ _new_ _()方法是对象的构造器的话,那么Python也提供了一个析构器,叫作_ _del_ _()方法。当对象将要被销毁的时候,这个方法就会被调用。但是需要注意的是,并非 del x 就相当于自动调用 x._ _del_ _(),_ _del_ _()方法是当垃圾回收机制回收这个对象的时候调用的。 举个例子:

Python中如何使用类和对象?

什么是绑定

前面提到过绑定的概念,那到底什么是绑定呢?Python中严格要求了方法需要有实例才能被调用,这种限制其实就是Python所谓的绑定概念。

有人可能会这么尝试,而且发现也可以调用:

Python中如何使用类和对象?

但是,这样做会有一个问题,就是根据类实例化后的对象根本无法调用里面的函数

Python中如何使用类和对象?

实际上是由于Python的绑定机制,这里自动把bb对象作为第一个参数传入,所以才会出现TypeError。

再看一个例子:

Python中如何使用类和对象?

_ _dict_ _属性是由一个字典组成,字典中仅有实例对象的属性,不显示类属性和特殊属性,键表示的是属性名值表示属性相应的数据值

Python中如何使用类和对象?

现在实例对象dd有了两个新属性,而且这两个属性是仅属于实例对象的:

Python中如何使用类和对象?

为什么会这样?其实这完全归功于self参数:当实例对象dd去调用setXY方法的时候,它传入的第一个参数就是dd,那么self.x = 4, self.y = 5也就相当于dd.x = 4, dd.y = 5,所以在实例对象,甚至类对象中都看不到x和y,是因为这两个属性是只属于实例对象dd的

如果把类实例删掉,实例对象dd还能否调用printXY方法?答案是可以的:

Python中如何使用类和对象?

本文内容来源于互联网,如有侵权请联系删除。
作者最新文章
编程开发 Python
相关文章 更多
Python安装后怎么打开:使用IDLE或命令行启动解释器
Python安装后怎么打开:使用IDLE或命令行启动解释器

刚在Windows安装好Python却不知道如何启动?本文详细演示如何通过开始菜单找到并打开IDLE集成开发环境,以及如何在PowerShell或命令提示符中使用python和py命令启动交互式解释器、运行.py脚本文件。包含退出解释器的方法及常见启动问题排查,帮助初学者快速验证安装成功并开始编写代码。

Windows系统Python安装教程:下载、勾选PATH及环境变量配置
Windows系统Python安装教程:下载、勾选PATH及环境变量配置

针对Windows初学者的Python安装实战指南。详细讲解如何从Python官网下载匹配架构的安装包,重点演示安装首屏勾选“Add python.exe to PATH”的关键操作,并提供使用python --version和py命令验证环境变量的具体步骤,帮助新手快速搭建开发环境并排查路径问题。

麒麟OS如何查看Python进程的运行状态
麒麟OS如何查看Python进程的运行状态

要想确认麒麟OS中Python程序的运行状态以及资源占用情况,我们可以这样做:用ps -ef | grep python来筛选进程;通过top命令,按P键排序查看实时负载;使用pgrep -f "script.py"精准获取PID;借助lsof -p PID验证文件打开状态。另外,还可以结合syst

Python在Debian上如何配置SSL证书
Python在Debian上如何配置SSL证书

在Debian系统上配置SSL证书通常涉及以下几个步骤:安装Web服务器:首先,你需要一个Web服务器,比如Apache或Nginx。这里以Apache为例。sudo apt updatesudo apt install apache2获取SSL证书:你可以从Let’s Encrypt免费获取SSL

统信UOS怎么安装Python开发环境
统信UOS怎么安装Python开发环境

要想让Python项目在统信UOS上正常运行,得先安装python3、python3-pip、python3-venv、python3-dev以及build-essential等组件。具体操作就是执行sudo apt install命令来一步到位完成安装,同时别忘了配置清华镜像源来给pip加速哦。在

纯Python方案实现中英文全文搜索
纯Python方案实现中英文全文搜索

在互联网上的各类网站中,无论大小,基本上都会有一个搜索框,用来给用户对内容进行搜索,小到站点搜索,大到搜索引擎搜索。从简单的来说,搜索功能确实很简单,一个简单的select语句就可以实现数据的搜索。而从复杂的来看,无论是搜索的精度还是搜索的效率,都是有很深的研究范围的。对于简单的搜索功能来说,一个s

Mac如何取消通过Python脚本运行的关机程序
Mac如何取消通过Python脚本运行的关机程序

立即在终端输入sudo shutdown -c取消倒计时关机,成功后显示“Shutdown cancelled”;若存在pmset重复任务,需再执行sudo pmset repeat cancel清除。Mac因Python脚本执行了os.system("sudo shutdown -h +10")或

Pythonasyncio异步并发与多固定出口IP调度实战
Pythonasyncio异步并发与多固定出口IP调度实战

之前写过一篇同步场景下用 Python 管理多个固定出口 IP 的实践(ExitPool + requests/httpx),覆盖了健康检查、故障转移和连接池复用。但在实际业务中,越来越多的场景用 asyncio 做高并发采集或批量接口调用——异步事件循环下多出口的管理方式和同步场景完全不同:单线程

Python在静态出口IP产品中的实战:从地址漂移巡检到多IP故障切换
Python在静态出口IP产品中的实战:从地址漂移巡检到多IP故障切换

写在前面:为什么静态出口 IP 不是"买了就行"不少团队在引入静态出口 IP 产品时,第一反应往往是:“地址配上去,这事就算完了。”可真到了真实业务里,静态出口 IP 真正能体现价值的地方,往往不在分配这一步,而在分配之后怎么管:地址有没有漂移,质量是否达标,某一条线路突然不可用时怎么切换,连接层又

using namespace 使用中遇到的问题怎么解决
using namespace 使用中遇到的问题怎么解决

命名空间的基本概念与常见引入问题在C++等编程语言中,命名空间(namespace)是一种将代码标识符(如变量、函数、类名)封装在特定名称下的机制,其主要目的是避免命名冲突,尤其是在大型项目或使用多个第三方库时。使用“using namespace”指令可以将指定命名空间中的所有名称引入当前作用域,

查看更多
精品专题 更多
装机必备
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows
Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

macOS软件
macOS软件

正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

Mac软件 更多
灵活计算器
灵活计算器
macOS/iOS/Android

灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

赤友清理大师
赤友清理大师
macOS

赤友清理大师是一款为 Mac 设计的智能清理优化工具,可精准扫描垃圾、大文件、重复文件等,释放磁盘空间。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

极度公式
极度公式
Windows/macOS/Linux

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

WINDOWS 更多
Windows 10
Windows 10
Windows

Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。

极度公式
极度公式
Windows/macOS/Linux

极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

密码键盘
密码键盘
Windows/macOS/iOS/Android

密码键盘是一款兼具安全性与便捷性的高效密码管理器。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。