目录:

类(class)和实例

整数、字符串、浮点数等,不同的数据类型就属于不同的类。

想想看当初学数据类型,我们用type验证数据类型后打印的结果

忘了就再来看看:

strs = '字符串'

ints = 1

floats = 2.3

print(type(strs)) #

print(type(ints)) #

print(type(floats)) #

以上,class就是类。

顾名思义class 'str'就表示是字符串类。

同理,剩下俩个就是整数类、浮点数类...

类之所以为类,是因为每一个类之下都包含无数相似的不同个例。

类,是对某个群体的统称。

比如:人类、犬类

实例

在Python的术语里,我们把类的个例就叫做实例 (instance),可理解为“实际的例子”。

比如上边代码中的'字符串'、1、2.3。这三个就分别是字符串类的实例、整数类的实例、浮点数类的实例。

类是某个群体,实例是群体中某个具体的个体。

群体里的每个个体都有着相同/相似的特征和行为。也就是说实例之间会有相同/相似的特征和行为。

比如,字符串中的实例举几个例子:

str1 = '我是字符串'

str2 = '1'

str3 = '2.3'

str4 = 'True'

以上四个都是字符串,因为他们都是用英文引号包裹。这就是他们的相同特征。

即使他们四个的内容值完全不一样。

而也因此,值不一样就是他们实例之间的区别、是区别于其他实例个体的特征。

小测试

请问:狗、秋田犬、忠犬八公、list、[1,2]

以上这五个元素,哪个是类、哪个是实例?

答案见源码同目录下files中同名py文件

对象(object)

佛说:万事万物,皆可为对象。

咳咳,佛说,我说的不是男女对象那个对象!

这里所谓Python中的对象,等于类和实例的集合:类可以看作是对象,实例也可以看作是对象。

比如列表list是个类对象,[1,2]是个实例对象,它们都是对象。

再比如说人类是个类对象,也可以说小红是个实例对象(这里小红依旧不是你的女对象!!!清醒点!!蚂蚁竞走了十年了!!!)。

属性和方法

区别于其他类的依据,细分可以分成两种:

第一种是描述事物是怎样的,有什么特征 - 这就是所说的【属性】

第二种是描述事物能做什么,有哪些行为和作用 - 也就是所说的【方法】

Python中每个类都有自己独特的属性(attribute)和方法(method),是这个类的所有实例都共享的。换言之,每个实例都可以调用类中所有的属性和方法。

不过各个类的属性和方法,是需要我们自行创建的。除了python中已有的数据类型其属性和方法是内置建好的。

比如:列表的内置方法有append、pop等。而这些方法任何列表实例值都可以使用

listObject = [1,3,'列表实例里的第三个元素']  # 一个列表实例

listObject.append('我是列表实例利用类上的append方法添加进来的元素') # 调用列表类的内置方法append

print(listObject) # [1, 3, '列表实例里的第三个元素', '我是列表实例利用类上的append方法添加进来的元素']

类的创建

上节,函数用def关键字定义。

本节,类的创建用class关键字定义。

伪代码

class 首字母大写的类变量名:

自定义属性名 = 属性值

def 自定义方法名(self,参数1,可以没有参数2):

方法函数体内容

具体的含义:

用class关键字创建,class+类名+英文冒号

类名首字母大写,是自定义命名,大写字母开头,不能和python关键字冲突。

类的代码体要放在缩进里。

属性名自定义,不能和python关键字冲突。属性值直接用等号赋值给自定义属性名即可

实例方法名自定义,不能和python关键字冲突。方法(也就是函数)通过def关键字定义,和函数的定义语句很类似,

实例方法的第一个参数必须传self,固定值。(下详)

类中创建的属性和方法可以被其所有的实例调用

实例的数目在理论上是无限的。我们可以同时“新建”多个实例【类被称为“实例工厂”的由来】

示例代码

# 创建一个男朋友类对象

class MyBoyfriend:

sex = 'male'

def caring(self):

print('好了,不哭了~')

boyfriend = MyBoyfriend() # 调用类对象,得到男朋友实例对象。

print(type(MyBoyfriend)) #

print(boyfriend) # <__main__.myboyfriend> MyBoyfriend类的是一个实例对象。后面的一串字符(0x109922400)表示这个对象的内存地址。

print(type(boyfriend)) #  表示boyfriend类属于MyBoyfriend类。

属性(attribute)

在类中赋值的变量叫做这个类的“属性”

方法(method)

在类中定义的函数叫做这个类的“方法”。

类中带self的参数的方法是实例方法,是类方法的一种形式,也是最常用的一种方法。

类的实例化

还是以上边创建男朋友类的代码为例,类的实例化过程就是MyBoyfriend()这句。

最后创建的实例对象被赋值给变量boyfriend。

调用类对象的过程叫作类的实例化,即用某个类创建一个实例对象。

实现形式/伪代码是

实例变量名 = 类名() # 类名后+小括号调用

实例对象调用类属性和方法

实例化类对象后,得到一个实例对象。因为类的方法和属性,实例对象都有。所以实例对象boyfriend可以调用类中的属性sex和方法caring。

调用类的属性

实例名.属性

调用类的方法

实例名.方法(传参) # 参数不用考虑self

示例代码

# 调用类的属性

print(boyfriend.sex) # 打印"male"

# 调用类的方法

boyfriend.caring() # 打印“好了,不哭了~”

值得说明的是,调用类方法时,传参不用考虑self参数的存在。

fa

特殊参数:self

可以看到上例,为什么实例调用方法时不用传参,在定义时那个参数self又是什么意思呢?

这个参数self的特殊之处:“在定义时不能丢,在调用时要忽略。”

1、代指实例化对象的作用

其实这个self有点像JS中构造函数内部的this。self是所有实例化对象的替身。指的是任何用这个类生成的实例化对象:

# self

class SelfMean:

content = '类SelfMean中的属性'

def oneFn(self):

print(self.content) # self在此指向实例化的对象"selfMean"

selfMean = SelfMean()

selfMean.oneFn() # 打印类中content的值 - "类SelfMean中的属性"

注意上例中,在oneFn函数内部,使用类中的属性content时,不能直接当变量使用,否则如下写法就会报错:

class SelfMean:

content = '类SelfMean中的属性'

def oneFn(self):

print(content) # 不用self调用类属性,就会报错NameError: name 'content' is not defined

selfMean = SelfMean()

selfMean.oneFn()

变量未经定义就使用,就会报这种NameError的问题。详见第三章错误类型总结篇。

有人会疑问,代码中oneFn上边不是定义了content还给她赋值了吗?怎么能说未定义呢?

函数的作用域中也说了,自己oneFn函数内部找不到的变量,会向上找父级作用域、层层向上查询乃至全局作用域的变量啊,他自己虽然没有、但是他爸爸有啊!为啥还说未定义呢?

同志啊,醒醒。这里是类啊!不是函数。类内部的变量是定义给实例化对象的属性的啊。换句话说,上述代码实例化对象转换成字典的模样长下边这样:

selfMean = {

'content': '类SelfMean中的属性',

'oneFn': 一个函数体在这里~

}

所以你如果不用字典的方式(1、selfMean.content;2、selfMean['content'])调用这个属性,他是拿不出来的。

而在类内部,实例化对象还没出生,你不知道他未来的名字叫selfMean1、还是叫selfMean37。也就没有办法用selfMean.content或selfMean37['content']的方式去调用它。

所以在这之前,需要有一个统一的self,来代指未来的实例化对象,并达到提前在类内部使用实例化对象的属性和方法的目的。

使用方式就是self.属性、self.方法名(除self以外的传参)。看下例:

class SelfMean:

content = '类SelfMean中的属性'

def oneFn(self):

print(self.content) # 提前在类中使用了实例化对象的属性 content,等价于selfMean.content

self.twoFn('哈哈哈哈哈~') # 提前在类中使用了实例化对象的方法 twoFn、并传参

def twoFn(self, txt):

print('实例化对象的第二个方法,打印内容:', txt)

selfMean = SelfMean()

selfMean.oneFn()

2、定义方法必传self

看上边的代码中,oneFn和twoFn都有self参数,并且都是第一个参数,这并不是巧合。

只要在类中定义的方法,第一个参数就必须是self。不过调用方法时,可以忽略它,不用给self传参。

3、调用方法传参时self可忽略

我们调用实例方法的时候,传参不用考虑self。以此往后类推就行:

class SelfParams:

content = '类SelfParams中的属性'

def twoFn(self,name,sex,age,weight):

print(self.content)

print(name,sex,age,weight) # 2、依次打印传递过来的位置参数的值:小石头 female 19 91

selfParams = SelfParams()

selfParams.twoFn('小石头','female',19,91) # 1、调用方法时忽略self参数,依次按位置传递name,sex,age,weight的参数

初始化方法(构造函数)

1、定义初始化方法

定义初始化方法的格式是def __init__(self),是由init关键字加左右两边的【双】下划线(__)组成。

双下划线是英文输入法下,shift + 0右边的那个键打出来的。

2、初始化方法的作用

无需调用自执行

一、当每个实例对象创建时(即类调用时),该方法内的代码无须调用就会自动运行。无需"实例名.init"的方式调用

# init

class InitTest:

def __init__(self):

a = 321

b = 345

print("初始化就会执行init里的代码: ", a+b)

initTest = InitTest()

# 运行后直接打印:初始化就会执行init里的代码:  666

可见 ,触发类对象的调用时,就直接触发了__init__方法的调用。

为类属性设置初始值

一般情况下,我们都会在初始化方法内部完成类属性的创建,为类属性设置初始值,这样类中的其他方法就能直接、随时调用。

上述代码改写如下:

class InitTest:

def __init__(self):

# 为类属性设置初始值,要写在__init__函数内部的最上方,否则会报错

self.a = 321 # 注意self的存在。

self.b = 345 # 同上

# 定义完属性的初始值以后,才能在下变写__init__里边要处理的其他逻辑

print("初始化就会执行__init__里的代码")

self.plusAd()

def plusAd(self):

print(self.a + self.b) # 使用类属性

initTest = InitTest()

# 打印结果如下

# 初始化就会执行init里的代码

# 666

3、初始化方法接收其他参数

除了设置固定常量,初始化方法同样可以接收其他参数,并把这些参数赋值给类的属性并被类中其他方法使用:

# 初始化方法接收参数

class InitParams:

def __init__(self,aP,bP):

self.a = aP

self.b = bP

print('初始化执行并设置属性、把参数aP和bP的值给了属性a和b')

self.plusAd()

def plusAd(self):

print(self.a + self.b) # 其他方法也能用同一个属性

def sub(self):

print(self.a - self.b) # 其他方法也能用公用的属性

initParams1 = InitParams(12, 4) # __init__需要的参数在类调用时传递

# 打印结果:

# 初始化执行并设置属性、把参数aP和bP的值给了属性a和b

# 16

# 8

initParams2 = InitParams(30, 5) # __init__需要的参数在类调用时传递,可以多次调用,传不同的参数,进而得到不一样的结果

# 打印结果:

# 初始化执行并设置属性、把参数aP和bP的值给了属性a和b

# 35

# 25

当初始化方法__init__有多个参数的时候,在实例化(类调用)的时候就要传入相应的值。

上例第一次调用,12传给了aP、4传给了bP。

上例第二次调用,30传给了aP、5传给了bP。

这也是初始化方法的好处,传参一次可被多次调用,

番外 - 面向对象

面向过程

面向过程编程:首先分析出解决问题所需要的步骤(即“第一步做什么,第二步做什么,第三步做什么”),然后用函数实现各个步骤,再依次调用。一个示例:

# 全局变量定义

globalA = 12

globalB = 20

globalCount = 0

# 加

def plus():

global globalCount

globalCount = globalA + globalB

sub()

# 减

def sub():

global globalCount

globalCount = globalCount - globalA/2

print(globalCount)

# 主流程

def main():

plus()

# 启动流程

main()

我们根据“全局变量数据整理——主流程——加法计算——减法计算”这个过程封装了三个函数,再依次调用,按规定顺序执行程序。

面向对象

面向对象编程,会将程序看作是一组对象的集合。通过调用对象的属性和方法,来拼凑完成一段功能。

# 面向对象

class Calculator:

def __init__(self,a,b):

# 公共属性定义

self.globalA = a

self.globalB = b

self.globalCount = 0

# 是加法方法,能做加法

def plus(self):

self.globalCount = self.globalA + self.globalB

print(self.globalCount)

# 是减法方法,能做减法

def sub(self):

self.globalCount = self.globalCount - self.globalA/2

print(self.globalCount)

calculator = Calculator(12,20)

calculator.plus()

calculator.sub()

用这种思维设计代码时,考虑的不是程序具体的执行过程(即先做什么后做什么),而是考虑先创建某个类,在类中设定好属性和方法,即是什么,和能做什么。

接着,再以类为模版创建一个实例对象,用这个实例去调用类中定义好的属性和方法(plus、sub)即可。

面向对象的好处

参数的传递会比普通函数要省事很多。(不必考虑全局变量和局部变量,因为类中的方法可以直接调用属性。)

代码的可复用性也更高。(类能封装更多的东西,既能包含操作数据的方法,又能包含数据本身。)

代码结构会更清晰。(代码的可读性、可拓展性和可维护性这几个方面都会优于面向过程编程。)

一目了然。(面向对象编程将代码具体的数据和处理方法都封装在类中,不用完全了解过程也可以调用类中的各种方法。并且还可以分开调用)

可以在 Python 中轻松地调用各种标准库、第三方库和自定义模块(别人写好的类框架代码)

本文使用 mdnice 排版

python class object_【python系统学习13】类(class)与对象(object)相关推荐

  1. 如何系统的自学python-自学Python应该如何正确系统学习,避免少走弯路

    原标题:自学Python应该如何正确系统学习,避免少走弯路 人生苦短,我用 Python. 学习 Python 的初学者往往会面临以下残酷的现状: 网上充斥着大量的学习资源.书籍.视频教程和博客,但是 ...

  2. 命名空间_python基础 13 类命名空间于对象、实例的命名空间,组合方法

    python基础 13 类命名空间于对象.实例的命名空间,组合方法 1.类命名空间于对象.实例的命名空间 创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 而类有两 ...

  3. java.io包对象读写_java.io 包中的____________和____________类主要用于对对象(Object)的读写_学小易找答案...

    [多选题]连铸钢水成分控制的要求有( ). [单选题]起动机用直流电动机将电能转化为 [单选题]下列关于我国少数民族传统禁忌的说法中,错误的是( ). [多选题]下列选项中 , 属于表单控件的是 ( ...

  4. python用psf函数_python学习之-类的内置函数

    内置方法:__str__(该方法必须返回字符串类型),在对像被打印时自动触发,然后将该方法的返回值当做打印结果输出) class People: def __init__(self,name,age) ...

  5. python简单代码input-【python系统学习05】input函数——实现人机交互

    input函数 目录 input用途 实现人机交互: 1.你提出问题打印在屏幕上, 2.运行程序的人再输入回答. 3.按下回车,程序得到收集来的回答 4.之后,逻辑向下继续运行. 我们写的程可以实现根 ...

  6. 计算机python指什么_系统学习python-1.1什么是计算机

    现代的计算机好像是万能的?它的内核是什么样的你知道吗? 从名字讲起 从名字可以看出来,计算机在发明出来时是用来计算的.简单的数学运算我们可以用笔或者心算完成,这样不仅劳神劳力还容易出错,更何况生活中还 ...

  7. c++学习13 类与对象(二)c++对象模型和this指针和友元

    类和对象 c++对象模型和this指针 成员变量和成员函数分开存储 在c++中类内的成员变量和成员函数分开存储 只有非静态成员变量才属于类的对象 #include<iostream> us ...

  8. python面向对象编程指南 豆瓣_一文看懂Python面向对象编程(Python学习与新手入门必看)-绝对原创...

    尽管网上有许多关于Python面向对像的编程介绍,小编我看完后总觉得不是很满意,也不过瘾,所以决定自己亲自动手写篇文章,帮你理解Python面向对象的编程的基本概念和核心思想.本文内含很多实例代码,以 ...

  9. 初学python,字典实现翻译系统

    初学python,字典实现翻译系统 学习字典时的突发奇想,不多说,上代码. #!/usr/bin/env python #-*- coding utf-8 -*- # author:luoyejing ...

最新文章

  1. 一文读懂序列建模(deeplearning.ai)之序列模型与注意力机制
  2. 五天带你学完《计算机网络》·第二天·数据链路层
  3. 学python编程_学习Python编程,我们应该如何学?学习内容包括哪些?
  4. 软件过程软件Scrum敏捷开发
  5. 充电桩系统php源码,源码 充电桩程序设计 - 下载 - 搜珍网
  6. Type mismatch: cannot convert from int to Object错误
  7. python循环引用是什么_细说Python的循环调用、循环引用和循环导入
  8. html浮动代码_清除浮动与 BFC(块级格式化上下文)
  9. nofollow标签_SEO技术动态:谷歌升级Nofollow标签的作用
  10. 简书UI易用性缺陷:投稿按钮太小
  11. java中rhino什么用_使用require.js和Java / Rhino解析模块
  12. 为VMware ESXi主机添加本地存储的过程及注意事项-之3
  13. zabbix内网安装部署_搭建环境tomcat+nginx+keepalived+zabbix
  14. mappedBy reference an unknown target entity property解决方法
  15. 项目中用setTimeout代替setInterval
  16. 翟菜花:汽车市场首度遇冷,下沉市场与二手车会是破冰利器吗?
  17. PACS系统源码 影像管理系统源码(PACS)
  18. 给笔记本电脑外接显示器增加副屏
  19. App上架时,华为应用市场提示:在测试环境:Wi-Fi联网、EMUI11.0 ( P40),软件存在闪退。如何模拟EMUI11.0 ( P40)
  20. 湘潭大学计算机组成原理试卷,湘潭大学11级原理课堂测验题集.ppt

热门文章

  1. WPS无法清除云文档
  2. 字符串匹配算法(BF、KMP)
  3. Gmail,Qmail,163等邮件服务器SMTP、IMAP、POP3、地址及SSL/非SSL协议端口号
  4. nodejs基于vue 网上商城购物系统
  5. cmake-下载和安装
  6. 初学python100例-案例22 输出三角形图案 青少年python编程 少儿编程案例讲解
  7. dbgview问题:Could not extract Debug View driver to c:\Windows\System32\Drivers\Dbgv.sys
  8. java_web1:基本标签、form表单、frameset框架标签、CSS样式、javascript、servlet
  9. java反射 注解_Java反射中的注解
  10. 计算机软件技术基础 王海燕,北大考研辅导班:2021北京大学工学院机械硕士(085500)考研招生分析、参考书目、复试线等经验指导篇...