python采用面向对象编程模式吗_如何理解 Python 中的面向对象编程?

现如今面向对象编程的使用非常广泛,本文我们就来探讨一下Python中的面向对象编程。

e824b899a9014c08c6f442c29d21820d7af4f46e.jpeg?token=5cfaa8c6016058bdeee1bcf27718e388&s=FD3F30D48A768CCE5F1FA3830300B08E

作者 | Radek Fabisiak

译者 | 弯月,责编 | 郭芮

以下为译文:

Python支持多种类型的编程范式,例如过程式编程、函数式编程、面向对象编程,而且还可以融合多种类型的范式。

现如今面向对象编程的使用非常广泛。面向对象编程的基本元素是对象,其包含的数据成员称为属性,函数(例程、过程)称为方法。

对象是类的实例。换句话说,类主要定义对象的结构,然后我们以类为模板创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。

本文我们来探讨一下Python中的面向对象编程。我们将演示如何创建类,并使用类来实例化对象。本文的主要内容如下:

创建Python类数据属性实例方法属性类和静态方法继承本文无法涵盖这些主题的所有详细信息。Python中的面向对象编程还包含其他很多方面。希望本文能够为你学习Python及实现面向对象提供一个良好的开端。

创建Python类

我们可以使用关键字class定义Python类,关键字后面紧跟类的名称、分号和类的实现:

>>> classMyClass:... pass...

按照惯例,Python类的命名采用首字母大写(即PascalCase)。

现在让我们创建这个新类的一个实例,名为MyClass:

>>> a = MyClass()>>> a<__main__.MyClass object at 0x7f32ef3deb70>

语句a = MyClass()创建了MyClass的一个实例,并将它的引用赋值给变量a。

我们可以通过Python内置的函数type()或直接通过属性.__class__来获取类型(即对象的类)。在拿到类(类型)之后,我们就可以利用属性.__ name__获取类的名字:

>>> type(a)>>> a.__class__>>> a.__class__.__name__'MyClass'

顺便提一句,Python类也是对象。它们是type的实例:

>>> type(MyClass)

下面,我们来定义一个方法。

Python中每个实例方法的第一个参数必须对应于该实例,即该对象本身。按照惯例,这个参数名为self。后面是其他参数(如果有需要的话)。在调用方法时,我们无需明确提供与参数self相对应的参数。

通常,我们需要定义的一个最重要的方法是.__init__()。在类的实例创建后就会调用这个方法。该方法负责初始化类成员。我们定义的.__init__()如下:

>>> classMyClass:... def__init__(self, arg_1, arg_2, arg_3):... print(f'an instance of {type(self).__name__} created')... print(f'arg_1: {arg_1}, arg_2: {arg_2}, arg_3: {arg_3}')...

下面,我们来创建一个MyClass实例,看看这个初始化方法的具体工作。我们的.__init__()方法需要三个参数(arg_1、arg_2和arg_3),记住我们不需要传递与self对应的第一个参数。所以,在实例化对象时,我们需要传递三个参数:

>>> a = MyClass(2, 4, 8)an instance ofMyClass createdarg_1: 2, arg_2: 4, arg_3: 8

上述声明产生的结果如下:

创建一个MyClass类型的对象的实例。自动调用该实例的方法.__init__()。我们传递给MyClass()方法的参数:(2,4和8)会被传递给.__init__()。.__init__()执行我们的请求,并输出结果。它利用type(self).__name__获取类的名称。现在我们得到了一个类,它有一个方法.__init__(),以及这个类的一个实例。

数据属性

下面我们来修改MyClass,增加一些数据属性。

我们利用.__init__()初始化和定义了实例,我们还可以在这个方法或其他实例方法中,通过给某个数据属性赋值的方式改变属性值:

>>> classMyClass:... def__init__(self, arg_1, arg_2, arg_3):... self.x = arg_1... self._y = arg_2... self.__z = arg_3...

现在MyClass有三个数据属性:

.x可以获取arg_1的值._y可以获取arg_2的值.__ z可以获取arg_3的值我们可以利用Python的解包机制,用更紧凑的形式编写这段代码:

>>> classMyClass:... def__init__(self, arg_1, arg_2, arg_3):... self.x, self._y, self.__z = arg_1, arg_2, arg_3...

属性名称中的下划线(_)是为了表明这些属性是“私有”属性:

开头没有下划线的属性(比如.x)通常可供对象外部的调用和修改。开头拥有一个下划线的属性(比如._y)通常也可以从对象外部调用和修改。然而,下划线是一种惯用的标志,即该类的创建者强烈建议不要使用该变量。应该仅通过类的功能成员(比如方法和属性)调用和修改该变量。开头拥有双下划线的属性(比如.__ z)将在名字修饰过程中被改名(在本例中它将被改名为._MyClass__z)。你也可以通过这个新名称从对象外部调用和修改它们。但是,我强烈反对这种做法。应该尽通过类的功能成员以其原始名称进行调用和修改。Python对象的数据属性通常存储在名为.__ dict__的字典中,它也是对象的属性之一。但是,你也可以将数据属性存储在其他地方。我们可以直接访问__dict__,或利用Python的内置函数vars()获取.__ dict__:

>>> a = MyClass(2, 4, 8)>>> vars(a){'x': 2, '_y': 4, '_MyClass__z': 8}>>> a.__dict__{'x': 2, '_y': 4, '_MyClass__z': 8}

名字修饰过程把键'__z'变成了'_MyClass__z'。

我们可以把.__ dict__当成普通的Python字典使用。

获取和修改与数据属性关联的值的常规方法如下:

>>> a.x2>>> a._y4>>> a.__zTraceback (most recent call last): File "", line 1, in AttributeError:'MyClass' object has no attribute '__z'>>> a.x = 16>>> a.x16>>> vars(a){'x': 16, '_y': 4, '_MyClass__z': 8}

请注意,我们无法访问.__ z,因为.__ dict__没有键'__z'。

实例方法

下面,我们来创建两个实例方法:

●.set_z():修改.__ z。

●.get_z():返回.__ z的值。

请记住,每个实例方法的第一个参数(按照约定名为self)引用对象本身,但我们无需在调用方法时指定这个参数:

>>> classMyClass:... def__init__(self, arg_1, arg_2, arg_3):... self.x, self._y, self.__z = arg_1, arg_2, arg_3... ... defset_z(self, value):... self.__z = value... ... defget_z(self):... returnself.__z...>>> b = MyClass(2, 4, 8)

方法.get_z()和.set_z()提供了传统的检索和修改.__ z值的方法:

>>> b.get_z()8>>> b.set_z(16)>>> vars(b){'x': 2, '_y': 4, '_MyClass__z': 16}

你也可以在.get_z()和.set_z()中添加其他功能,例如检查数据的有效性。这种方法实现了面向对象编程中的一个主要概念:封装。

属性

还有一种方法(一种更Python的方式)访问和修改数据属性是使用属性。属性封装了一系列方法:getter、setter和deleter,但其行为与普通的数据属性相同。

下面的代码实现了属性.z,其中还包含.get_z()和.set_z()的功能:

>>> classMyClass:... def__init__(self, arg_1, arg_2, arg_3):... self.x, self._y, self.__z = arg_1, arg_2, arg_3... ... @property... defz(self):... returnself.__z... ... @z.setter... defz(self, value):... self.__z = value...>>> b = MyClass(2, 4, 8)

如下,我们利用相应的属性.z来访问和修改数据属性.__ z:

>>> b.z8>>> b.z = 16>>> vars(b){'x': 2, '_y': 4, '_MyClass__z': 16}

这段代码比上述示例更精简优雅。

类与静态方法

除了实例方法和属性之外,类还可以拥有类方法和静态方法。

下面让我们为MyClass添加三个方法:

>>> classMyClass:... def__init__(self, arg_1, arg_2, arg_3):... self.x, self._y, self.__z = arg_1, arg_2, arg_3... ... deff(self, arg):... print('instance method f called')... print(f'instance: {self}')... print(f'instance attributes:\n{vars(self)}')... print(f'class: {type(self)}')... print(f'arg: {arg}')... ... @classmethod... defg(cls, arg):... print('class method g called')... print(f'cls: {cls}')... print(f'arg: {arg}')... ... @staticmethod... defh(arg):... print('static method h called')... print(f'arg: {arg}')...>>> c = MyClass(2, 4, 8)

方法.f()是一个实例方法。实例方法的第一个参数是对象本身的引用。这些方法可以利用self访问对象,利用vars(self)或self.__dict__访问对象的数据属性,还可以利用type(self)或self.__class__访问对象对应的类,而且它们还可以拥有自己的参数。

方法.g()的开头包含修饰器@classmethod,表明这是一个类方法。每个类方法的第一个参数都会指向类本身,按照约定该参数名为cls。与实例方法的情况一样,我们不需要明确提供与cls对应的参数。而类方法可以利用cls和自己的参数访问类本身。

方法.h()的开头包含修饰器@staticmethod,表明这是一个静态方法。静态方法只能访问自己的参数。

Python中常见的调用实例方法的方法如下:

>>> c.f('my-argument')instance method f calledinstance: <__main__.MyClass object at 0x7f32ef3def98>instance attributes:{'x': 2, '_y': 4, '_MyClass__z': 8}class: arg: my-argument

通常,我们应该直接通过类(而不是实例)调用类方法和静态方法:

>>> MyClass.g('my-argument')classmethodgcalledcls: arg: my-argument>>> MyClass.h('my-argument')static method h calledarg: my-argument

请记住,我们不需要传递类方法的第一个参数:与cls相对应的参数。

但是,我们可以像下面这样调用类方法和静态方法:

>>> c.g('my-argument')classmethodgcalledcls: arg: my-argument>>> c.h('my-argument')static method h calledarg: my-argument

当我们调用c.g或c.h,但实例成员没有这样的名称时,Python会搜索类和静态成员。

继承

继承是面向对象编程的另一个重要特性。在这个概念中,类(称为子类或派生类)会继承其他类(称为超类或基类)的数据和函数成员。

在Python中,所有类都会默认继承Python自带的类对象。但是,我们可以根据需要定义合适的类继承层次结构。

例如,我们可以创建一个名为MyOtherClass的新类,该类继承了MyClass:

>>> classMyOtherClass(MyClass):... def__init__(self, u, v, w, x, y, z):... super().__init__(x, y, z)... self.__u, self.__v, self.__w = u, v, w... ... deff_(self, arg):... print('instance method f_ called')... print(f'instance: {self}')... print(f'instance attributes:\n{vars(self)}')... print(f'class: {type(self)}')... print(f'arg: {arg}')...>>> d = MyOtherClass(1, 2, 4, 8, 16, 32)

如上,MyOtherClass拥有MyClass的成员:.x、._y、.__z以及.f()。你可以通过语句super().__init__(x, y, z)初始化基类的数据成员x、._y和.__z,该语句会调用基类的.__init__()方法。

除此之外,MyOtherClass还有自己的成员:.__u、.__v、.__w和.f_()。

下面,我们通过vars()获取数据成员:

>>> vars(d){'x': 8,'_y': 16,'_MyClass__z': 32,'_MyOtherClass__u': 1,'_MyOtherClass__v': 2,'_MyOtherClass__w': 4}

我们可以调用基类和派生类中的所有方法:

>>> d.f('some-argument')instance method f calledinstance: <__main__.MyOtherClass object at 0x7f32ef3e7048>instance attributes:{'x': 8,'_y': 16,'_MyClass__z': 32,'_MyOtherClass__u': 1,'_MyOtherClass__v': 2,'_MyOtherClass__w': 4}class: arg: some-argument>>> d.f_('some-argument')instance method f_ calledinstance: <__main__.MyOtherClass object at 0x7f32ef3e7048>instance attributes:{'x': 8,'_y': 16,'_MyClass__z': 32,'_MyOtherClass__u': 1,'_MyOtherClass__v': 2,'_MyOtherClass__w': 4}class: arg: some-argument

但是,如果派生类包含的某个成员与基类同名,则优先使用派生类的成员。

总结

面向对象编程是Python支持的编程范式之一。面向对象蕴含的抽象以及表征的现实世界行为在某些时候会非常有帮助性。然而,有时也可能会违反直觉,并为开发过程带来不必要的麻烦。

在本文中,我们介绍了如何利用Python编写基本的面向对象程序。Python中还有很多类和面向对象的功能,例如:

方法:.__repr__()和.__str__()方法:.__new__()操作符方法:.__getattribute__()、.__getattr__()、.__setattr__()和.__delattr__()生成器可调用性创建序列描述器上下文管理抽象类和成员多重继承使用super()拷贝序列化slot类修饰器数据类等等……

现如今面向对象是非常流行的编程方式。如果你立志做一名Python开发人员,那么就应该学习面向对象编程。但请不要忘记,Python还支持其他编程范式,例如过程式编程、函数式编程等,在某些情况下也许选用这些范例更为合适。

尽情享受编程的快乐!

原文:https://www.blog.duomly.com/object-oriented-programming-in-python/

本文为 CSDN 翻译,转载请注明来源出处。

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

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

相关文章

上传文件的php代码,PHP实现大文件上传源代码

PHP实现大文件上传源代码PHP 基础教程 PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。 PHP 是免费的&#xff0c;并且使用广泛。 以下是小编为大家搜索整理的PHP实现大文件上传源代码&#xff0c;希望能给大家带来帮助!更多精彩内容请及时关注我们应届毕业生考试!经…

android 打开系统相册_这5款常用Android手机自动化测试工具你要收藏

1、Monkey是Android SDK自带的测试工具&#xff0c;在测试过程中会向系统发送伪随机的用户事件流&#xff0c;如按键输入、触摸屏输入、手势输入等)&#xff0c;实现对正在开发的应用程序进行压力测试&#xff0c;也有日志输出。实际上该工具只能做程序做一些压力测试&#xff…

php 替换某个字符,php中如何替换字符串中的某个字符-PHP问题

正在PHP中&#xff0c;能够应用strtr()函数完成字符串交换。起首咱们简略理解下strtr()函数的界说及语法。语法&#xff1a;string strtr( string $str, string $from, string $to)第一个参数示意待转换的字符串。第二个参数示意字符串中与将要被转换的目的字符 to 绝对应的源字…

python提示对话框自动关闭_Python实现定时自动关闭的tkinter窗口方法

Python实现定时自动关闭的tkinter窗口方法 更新时间&#xff1a;2019年02月16日 09:13:27 作者&#xff1a;Python_小屋 今天小编就为大家分享一篇Python实现定时自动关闭的tkinter窗口方法&#xff0c;具有很好的参考价值&#xff0c;希望对大家有所帮助。一起跟随小编过来看看…

x5内核有什么优点_接上U盘就是NAS私有云,蒲公英X5入手测评

接上U盘就是NAS私有云&#xff0c;蒲公英X5入手测评&#xff01;现在很多人喜欢在家里配置一台NAS&#xff0c;这样远程访问家里的数据不仅方便&#xff0c;而且可以即时备份PC以及手机等设备的数据。一旦手机丢失或电脑数据损坏&#xff0c;还可以通过NAS来恢复数据。但是对于…

小程序如何调用php程序,微信小程序调用PHP后台接口 解析纯html文本

搜索热词1、微信js动态传参&#xff1a;PHP/Home/Xiaoxxf/activity_detail?a_idoptions.id,//含富文本htmldata: {is_detail:1},method: GET,// OPTIONS,GET,HEAD,POST,PUT,DELETE,TRACE,CONNECTheader: {Content-Type: application/json},success: function (res) {that.setD…

手机联系人头像包_一组抖音上很火的表情包,这里都有,一起来可可爱爱吧

我是最新抖音表情包马上到表情包轿车带火花|马上到表情包白色汽车动图em..不知道为什么这个表情包也很火&#xff0c;感jio没什么特别&#xff0c;这个就厉害了&#xff0c;你以为我是雨伞&#xff1f;那你就错了。砰~可可爱爱&#xff01;太萌了。像不像考试中的你&#xff1f…

python视频处理代码_python如何实现视频转代码视频

本文实例为大家分享了python如何实现视频转代码视频的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下 # -*- coding:utf-8 -*- #coding:utf-8 import argparse import os import cv2 import subprocess from cv2 import VideoWriter, VideoWriter_fourcc, imread, re…

遵义大数据中心项目工程概况_中策大数据:8月建筑工程项目有哪些?建筑工程项目信息汇总...

2020年8月建筑工程项目有哪些&#xff1f;中策大数据中国工程网为你搜集整理出了建筑工程项目信息&#xff0c;包括项目环评、施工单位招标、施工建设、项目设计、立项审批等各个工程项目阶段的拟在建项目。2020年8月建筑工程项目信息汇总&#xff1a;山东省济南温泉城通用航空…

python中str是什么_python的str()字符串类型的方法详解

字符串一旦创建&#xff0c;不可修改&#xff0c;一旦修改或者拼接&#xff0c;都会造成重新生成字符串&#xff0c;因为内存存数据是一个挨着一个存的&#xff0c;如果增加一个字符串的话&#xff0c;之前的老位置只有一个地方&#xff0c;不够&#xff0c;这是原理性的东西&a…

php什么程度算学会,十天学会PHP - 序1,学会的标准是什么?(20180820-1)

学会的标准是什么十天学会&#xff0c;这种名称难免给人“浮躁”之感&#xff0c;所以要和大家稍作解释。很多同学认为&#xff0c;学会 达到目的&#xff0c;这个看法过于主观&#xff0c;比如想就业、创业、做毕业设计&#xff0c;他们所需要的专业知识差异很大&#xff0c;…

空间皮肤代码_不废话,看我20行代码搞定色块提取与定位…….

点击上方蓝字关注我们微信公众号&#xff1a;OpenCV学堂关注获取更多计算机视觉与深度学习知识问题来由这个问题是谁问我的我已经不记得了&#xff0c;刚开始的时候他发了这张图像给我&#xff0c;让我给他看一下&#xff0c;我当时告诉他转换一下色彩空间提取就好啦&#xff0…

python字符串怎么表示_python中字符串的几种表达方式(用什么方式表示字符串)...

原博文 2018-11-21 18:45 − 说明: 今天在学习python的基础的内容,学习在python中如何操作字符串,在此记录下. 主要是python中字符串的几种表达&#xff0c;表示方式。 python的几种表达方式 1 使用单引号扩起来字符串 >>> my python lession #以单引号将字符串扩...0…

dw如何写php代码提示,DW CS5 jquery代码提示插件

喜欢使用Dreamweaver(业内简称dw)做php开发的朋友应该都知道dw是从6.0开始才支持jquery代码提示的。那么对于电脑上安装的是dw cs5而又需要jquery代码提示的该怎么办呢&#xff1f;将cs5卸了然后安装6吗&#xff1f;这个方法不是很妥&#xff0c;毕竟现在dw cs软件已经是几百兆…

python3.6 django部署_Apache2+Django+Python3.6部署-

本文指导安装Apache2, mod_wsgi 4.6.5, Django2.1,以及安装过程中可能出现的问题及解决方法。1,安装Apache2.4我本机是Ubuntu16.04的系统,如果时CenterOS&#xff0c;使用yum安装就好了.sudo apt install apache2 这个安装一般没有什么问题2,源码编译安装Python3.6源码地址&…

python中文文本分析_python使用snownlp进行中文文本处理以及分词和情感分析 - pytorch中文网...

SnowNLP: 一个简单的中文文本处理库 SnowNLP是一个python写的类库&#xff0c;可以方便的处理中文文本内容&#xff0c;是受到了TextBlob的启发而写的&#xff0c;由于现在大部分的自然语言处理库基本都是针对英文的&#xff0c;于是写了一个方便处理中文的类库&#xff0c;并且…

php异步方案,php 伪异步执行实现方法

需求描述&#xff1a;客户端访问php文件&#xff0c;php需要做某个耗时的操作。例如&#xff1a;访问远程接口数据 而客户端不需耗时操作的结果只期望快速得到输出.php本身是不支持异步操作的&#xff0c;可以用子进程的方式模拟异步操作执行&#xff0c;但实现起来比较复杂而且…

python原理与架构_Python:爬虫原理和网页构造

入门网络数据爬取&#xff0c;也就是Python爬虫现实中我们使用浏览器访问网页时&#xff0c;网络是怎么运转的&#xff0c;做了什么呢&#xff1f;首先&#xff0c;必须了解网络连接基本过程原理&#xff0c;然后&#xff0c;再进入爬虫原理了解就好理解的多了。1、网络连接原理…

flutter打包的app有多大_前端大势所趋---Flutter 这篇文章会让你行动起来

Flutter和原生APP的性能对比前言自从今年google IO大会推出flutter跨平台开发框架以来&#xff0c;flutter在各个技术论坛里被吵得如日中天。flutter团队直言flutter可以帮助开发者轻松实现恒定60fps的性能体验。我们知道flutter跨平台的原理是采用dart语言预编译的方式直接编译…

用java创建窗口程序,创建窗口的应用程序

创建窗口的应用程序通过前面的基础知识的学习&#xff0c;已经对ctypes库的基本功能学会了使用&#xff0c;为了加强这种知识训练&#xff0c;以及运用刚学习的知识的快乐&#xff0c;我们来创建一个稍稍复杂一点的应用程序。这个应用程序是所有后面应用程序的基础&#xff0c;…