python总结(3)

创建自定义类

终于要创建自定义类了!下面是一个简单的示例:

class Person:def set_name(self, name):self.name = namedef get_name(self):return self.namedef greet(self):print("Hello, world! I'm {}.".format(self.name))

这个示例包含三个方法定义,它们类似于函数定义,但位于class语句内。Person当然是类的名称。class语句创建独立的命名空间,用于在其中定义函数。一切看起来都挺好,但你可能想知道参数self是什么。它指向对象本身。那么是哪个对象呢?下面通过创建两个实例来说明这一点。

foo = Person()bar = Person()foo.set_name('Luke Skywalker’)bar.set_name("Anakin Skywalker’)foo.greet()Hello, world! I'm Luke Skywalker.bar. greet()Hello, world! I'm Anakin Skywalker.

这个示例可能有点简单,但澄清了self是什么。对foo调用set name和greet时,foo都会作为第一个参数自动传递给它们。我将这个参数命名为self,这非常贴切。实际上,可以随便给这个参数命名,但鉴于它总是指向对象本身,因此习惯上将其命名为self.显然,self很有用,甚至必不可少。如果没有它,所有的方法都无法访问对象本身–要操作的属性所属的对象。与以前一样,也可以从外部访问这些属性。

 foo. nameLuke Skywalkerbar.name ='Yodabar.greet()Hello, world! I'm Yoda.

提示 如果foo是一个Person实例,可将foo.greet0)视为Person.greet(foo)的简写,但后者的多态性更低。

属性、函数和方法

实际上,方法和函数的区别表现在前面提到的参数self上。方法(更准确地说是关联的方法)将其第-个参数关联到它所属的实例,因此无需提供这个参数。无疑可以将对象的属性关联到一个普通函数,但这样就没有特殊的self参数了。

class Class:def method(self):...print('I have a self!’)def function():print("I don't...")instance = Class()instance.method() instance.method = functioninstance.method() I don't...

请注意,有没有参数self并不取决于是否以刚才使用的方式(如instance.method)调用方法。实际上完全可以让另一个变量指向同一个方法。

 class Bird:song =’Squaawk!’def sing(self):print(self. song)bird = Bird()bird. sing()Squaawk!birdsong = bird.singbirdsong()Squaawk!

虽然最后一个方法调用看起来很像函数调用,但变量birdsong指向的是关联的方法bird.sing,这意味着它也能够访问参数self(即它也被关联到类的实例)。

再谈隐藏

默认情况下,可从外部访问对象的属性。再来看一下前面讨论封装时使用的示例。

c.nameSir Lancelotc.name ='Sir Gumby’c.get name()Sir Gumby

有些程序员认为这没问题,但有些程序员(如Smalltalk雅之父)认为这违反了封装原则。他们认为应该对外部完全隐藏对象的状态(即不能从外部访问它们)。你可能会问,为何他们的立场如此极端?由每个对象管理自己的属性还不够吗?为何要向外部隐藏属性?毕竟,如果能直接访问ClosedObject(对象c所属的类)的属性name,就不需要创建方法setName和getName了,关键是其他程序员可能不知道(也不应知道)对象内部发生的情况。例如,ClosedObject可能在对象修改其名称时向管理员发送电子邮件。这种功能可能包含在方法set_name中。但如果直接设置c.name,结果将如何呢?什么都不会发生–根本不会发送电子邮件。为避免这类问题,可将属性定义为私有。私有属性不能从对象外部访问,而只能通过存取器方法(如get name和set name)来访问。

Python没有为私有属性提供直接的支持,而是要求程序员知道在什么情况下从外部修改属性是安全的,。毕竟,你必须在知道如何使用对象之后才能使用它。然而,通过玩点小花招,可获得类似于私有属性的效果。要让方法或属性成为私有的(不能从外部访问),只需让其名称以两个下划线打头即可。

class Secretive:def __inaccessible(self):print("Bet you can't see me ...")def accessible(self):print( The secret message is:")self.__inaccessible()

现在从外部不能访问 inaccessible,但在类中(如accessible中)依然可以使用它

s= Secretive()s.inaccessible()s.accessible()The secret message is:Bet you can't see me ..

虽然以两个下划线打头有点怪异,但这样的方法类似于其他语言中的标准私有方法。然而,幕后的处理手法并不标准:在类定义中,对所有以两个下划线打头的名称都进行转换,即在开头加上一个下划线和类名。

Secretive.__Secretive__inaccessible

只要知道这种幕后处理手法,就能从类外访问私有方法,然而不应这样做。

s. __Secretive__inaccessible()Bet you can't see me .

总之,你无法禁止别人访问对象的私有方法和属性,但这种名称修改方式发出了强烈的信号,让他们不要这样做。

类的命名空间

下面两条语句大致等价:

def foo(x): return x*xfoo=lambda x:x*x

它们都创建一个返回参数平方的函数,并将这个函数关联到变量foo。可以在全局(模块)作用域内定义名称foo,也可以在函数或方法内定义。定义类时情况亦如此:在class语句中定义的代码都是在一个特殊的命名空间(类的命名空间)内执行的,而类的所有成员都可访问这个命名空间。类定义其实就是要执行的代码段,并非所有的Python程序员都知道这一点,但知道这一点很有帮助。例如,在类定义中,并非只能包含def语句。

class C:print('Class C being defined...)Class C being defined.

这有点傻,但请看下面的代码:

class MemberCounter:members=0def init(self):MemberCounter.members += 1m1 = MemberCounter()ml.init()MemberCounter.members1m2 = MemberCounter()m2.init()2MemberCounter.members

上述代码在类作用域内定义了一个变量,所有的成员(实例)都可访问它,这里使用它来计算类实例的数量。注意到这里使用了init来初始化所有实例,每个实例都可访问这个类作用域内的变量,就像方法一样。

m1.membersm2.members

如果你在一个实例中给属性members赋值,结果将如何呢?

 m1.members ='Two'm1.membersTwom2.members2

新值被写入m1的一个属性中,这个属性遮住了类级变量。

指定超类

本章前面讨论过,子类扩展了超类的定义。要指定超类,可在class语句中的类名后加上超类名,并将其用圆括号括起。

class Filter:def init(self):self.blocked=[]def filter(self,sequence):return [x for x in sequence if x not in self.blocked# SPAMFilter是Filter的子类class SPAMFilter(Filter):def init(self):#重写超类Filter的方法initself.blocked = ['SPAM’]

Filter是一个过滤序列的通用类。实际上,它不会过滤掉任何东西。

f = Filter()f.init ()f.filter([1, 2,3])[1,2,3]

Filter类的用途在于可用作其他类(如将’SPAM’从序列中过滤掉的SPAMFilter类)的基类(超类)

s=SPAMFilter()s.init()s.filter(['SPAM'.'SPAM','SPAM','SPAM','eggs’,’SPAM,’bacon '])bacon’"eggs

请注意SPAMFilter类的定义中有两个要点。

口 以提供新定义的方式重写了Filter类中方法init的定义

口 直接从Filter类继承了方法filter的定义,因此无需重新编写其定义。

第二点说明了继承很有用的原因:可以创建大量不同的过滤器类,它们都从Filter类派生而来,并且都使用已编写好的方法filter。这就是懒惰的好处。

面向对象设计总结:

口将相关的东西放在一起。如果一个函数操作一个全局变量,最好将它们作为一个类的属性和方法,。

口 不要让对象之间过于亲密。方法应只关心其所属实例的属性,对于其他实例的状态,让它们自己去管

理就好了。

口慎用继承,尤其是多重继承。继承有时很有用,但在有些情况下可能带来不必要的复杂性。要正确地

使用多重继承很难,要排除其中的bug更难。

口 保持简单。让方法短小紧凑。一般而言,应确保大多数方法都能在30秒内读完并理解。对于其余的方法,尽可能将其篇幅控制在一页或一屏内。

确定需要哪些类以及这些类应包含哪些方法时,尝试像下面这样做,

(1)将有关问题的描述(程序需要做什么)记录下来,并给所有的名词、动词和形容词加上标记

(2)在名词中找出可能的类。

(3)在动词中找出可能的方法。

(4)在形容词中找出可能的属性

(5)将找出的方法和属性分配给各个类.

有了面向对象模型的草图后,还需考虑类和对象之间的关系(如继承或协作)以及它们的职责。为进-步改进模型,可像下面这样做。

(1)记录(或设想)一系列用例,即使用程序的场景,并尽力确保这些用例涵盖了所有的功能,

(2)透彻而仔细地考虑每个场景,确保模型包含了所需的一切。如果有遗漏,就加上;如果有不太对的地方,就修改。不断地重复这个过程,直到对模型满意为止。

有了你认为行之有效的模型后,就可以着手编写程序了。你很可能需要修改模型或程序的某些部分,所幸这在Python中很容易,请不用担心。只管按这里说的去做就好。

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

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

相关文章

word毕业论文“et al.”替换为“等”——宏

Sub 中文参考文献改等()中文参考文献改等 宏Selection.Find.ClearFormattingSelection.Find.Replacement.ClearFormattingWith Selection.Find.Text "([一-龥], )et al.".Replacement.Text "\1等.".Forward True.Wrap wdFindContinue.Format False.Ma…

网络编程-----服务器(多路复用IO 和 TCP并发模型)

一、单循环服务器模型 1. 核心特征 while(1){newfd accept();recv();close(newfd);}2. 典型应用场景 HTTP短连接服务&#xff08;早期Apache&#xff09;CGI快速处理简单测试服务器 3. 综合代码 #include <stdio.h> #include <sys/types.h> /* See NO…

typora高亮方案+鼠标侧键一键改色

引言 在typora里面有一个自定义的高亮, <mark></mark>>但是单一颜色就太难看了, 我使用人工智能, 搜索全网艺术家, 汇集了几种好看的格式,并且方便大家侧键一键 调用, 是不是太方便啦 ! 示例 午夜模式 春意盎然 深海蓝调 石墨文档 秋日暖阳 蜜桃宣言 使用方法 …

swift -(5) 汇编分析结构体、类的内存布局

一、结构体 在 Swift 标准库中&#xff0c;绝大多数的公开类型都是结构体&#xff0c;而枚举和类只占很小一部分 比如Bool、 Int、 Double、 String、 Array、 Dictionary等常见类型都是结构体 ① struct Date { ② var year: Int ③ var month: Int ④ …

从零开始学机器学习——初探分类器

首先给大家介绍一个很好用的学习地址:https://cloudstudio.net/columns 在上一节中,我们已经完成了对所有经过均衡和清洗的菜品数据的准备工作。接下来,我们将考虑使用多种算法,也就是不同的分类器,来构建模型。我们将利用这个数据集和各种分类器,基于一组特定的配料,预…

黑色RGB是什么

>好的&#xff0c;用户现在问的是“黑色rgb是什么”。我需要先理解用户的问题。之前用户在使用MATLAB调整网格线颜色时&#xff0c;可能看到了默认颜色是黑色&#xff0c;或者之前我提到过默认颜色是[0.15 0.15 0.15]&#xff0c;而用户可能现在想知道黑色的RGB值具体是什么…

做到哪一步才算精通SQL

做到哪一步才算精通SQL-Structured Query Language 数据定义语言 DDL for StructCREATE&#xff1a;用来创建数据库、表、索引等对象ALTER&#xff1a;用来修改已存在的数据库对象DROP&#xff1a;用来删除整个数据库或者数据库中的表TRUNCATE&#xff1a;用来删除表中所有的行…

《深度解析DeepSeek-M8:量子经典融合,重塑计算能效格局》

在科技飞速发展的今天&#xff0c;量子计算与经典算法的融合成为了前沿领域的焦点。DeepSeek-M8的“量子神经网络混合架构”&#xff0c;宛如一把钥匙&#xff0c;开启了经典算法与量子计算协同推理的全新大门&#xff0c;为诸多复杂问题的解决提供了前所未有的思路。 量子计算…

解决电脑问题(2)——主板问题

当电脑主板出现问题时&#xff0c;可以尝试以下解决方法&#xff1a; 外观检查与清洁 检查硬件连接&#xff1a;仔细查看主板上的各种硬件连接&#xff0c;包括 CPU、内存、显卡、硬盘、电源等的连接线是否松动或损坏。确保所有插头都牢固地插入相应的插槽中&#xff0c;如有松…

Java 大视界 -- Java 大数据在智能家居能源管理与节能优化中的应用(120)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

【网络】TCP常考知识点详解

TCP报文结构 TCP报文由**首部&#xff08;Header&#xff09;和数据&#xff08;Data&#xff09;**两部分组成。首部包括固定部分&#xff08;20字节&#xff09;和可选选项&#xff08;最多40字节&#xff09;&#xff0c;总长度最大为60字节。 1. 首部固定部分 源端口&…

算法1-6 一元三次方程求解

题目描述 有形如&#xff1a;ax3bx2cxd0 这样的一个一元三次方程。给出该方程中各项的系数&#xff08;a,b,c,d 均为实数&#xff09;&#xff0c;并约定该方程存在三个不同实根&#xff08;根的范围在 −100 至 100 之间&#xff09;&#xff0c;且根与根之差的绝对值 ≥1。要…

05.基于 TCP 的远程计算器:从协议设计到高并发实现

&#x1f4d6; 目录 &#x1f4cc; 前言&#x1f50d; 需求分析 &#x1f914; 我们需要解决哪些问题&#xff1f; &#x1f3af; 方案设计 &#x1f4a1; 服务器架构 &#x1f680; 什么是协议&#xff1f;为什么要设计协议&#xff1f; &#x1f4cc; 结构化数据的传输问题 …

大数据面试之路 (一) 数据倾斜

记录大数据面试历程 数据倾斜 大数据岗位 &#xff0c;数据倾斜面试必问的一个问题。 一、数据倾斜的表现与原因 表现 某个或某几个Task执行时间过长&#xff0c;其他Task快速完成。 Spark/MapReduce作业卡在某个阶段&#xff08;如reduce阶段&#xff09;&#xff0c;日志显…

仅仅使用pytorch来手撕transformer架构(3):编码器模块和编码器类的实现和向前传播

仅仅使用pytorch来手撕transformer架构(2)&#xff1a;编码器模块和编码器类的实现和向前传播 往期文章&#xff1a; 仅仅使用pytorch来手撕transformer架构(1)&#xff1a;位置编码的类的实现和向前传播 最适合小白入门的Transformer介绍 仅仅使用pytorch来手撕transformer…

《OpenCV》—— dlib(换脸操作)

文章目录 dlib换脸介绍仿射变换在 dlib 换脸中的应用 换脸操作 dlib换脸介绍 dlib 换脸是基于 dlib 库实现的一种人脸替换技术&#xff0c;以下是关于它的详细介绍&#xff1a; 原理 人脸检测&#xff1a;dlib 库中包含先进的人脸检测器&#xff0c;如基于 HOG&#xff08;方向…

机器学习中的梯度下降是什么意思?

梯度下降&#xff08;Gradient Descent&#xff09;是机器学习中一种常用的优化算法&#xff0c;用于最小化损失函数&#xff08;Loss Function&#xff09;。通过迭代调整模型参数&#xff0c;梯度下降帮助模型逐步逼近最优解&#xff0c;从而提升模型的性能。 1.核心思想 梯…

三、Docker 集群管理与应用

&#xff08;一&#xff09;项目案例 1、准备主机 &#xff08;1&#xff09;关闭防火墙&#xff0c;或者开放TCP端口2377&#xff08;用于集群管理通信&#xff09;、TCP/UPD端口7946&#xff08;用于节点之间的通信&#xff09;、UDP端口4789&#xff08;用于overlay网络流…

网络DNS怎么更改?

访问速度慢或某些网站无法打开?改变网络DNS设置可能会帮助解决这些问题。本文将详细介绍如何更改网络DNS&#xff0c;包括更改的原因、具体步骤。 一、为什么要更改DNS? 更改DNS的原因有很多&#xff0c;以下是一些主要的考虑因素&#xff1a;某些公共DNS服务器的响应速度比…

江科大51单片机笔记【12】DS18B20温度传感器(上)

写在前言 此为博主自学江科大51单片机&#xff08;B站&#xff09;的笔记&#xff0c;方便后续重温知识 在后面的章节中&#xff0c;为了防止篇幅过长和易于查找&#xff0c;我把一个小节分成两部分来发&#xff0c;上章节主要是关于本节课的硬件介绍、电路图、原理图等理论…