什么是类

百度百科:

类是对象的抽象,对象是对客观事物的抽象。

用通俗的话来说:

类是类别的意思,是数据类型。
对象是类别下的具体事物。

也就是说:

类是数据类型,对象是变量。

比如:

自定义一种数据类型:水果。那水果就是类。
由此数据类型创建一个变量:一个苹果。那这个苹果就是对象。
类是抽象的,对象是具体的。

类和对象的关系

类是一种数据类型,相当于一个模板,用于创建对象。
每一个对象都有自己独立的内存空间,用于存储数据成员。

比如:

人都有名字,年龄,性别等信息。这是一个类,是抽象的。
小明叫张明,18岁,男。这是一个对象,是具体的。

专业术语

封装了变量和函数的一种自定义的数据类型

  • 数据成员

类中的变量

  • 方法

类中的函数

  • 对象

由类创建的变量称作为对象

  • 实例化

创建一个对象。
因为类是抽象的,而对象是具体的,是一个实例,所以通过类创建对象的过程称为实例化。

  • 继承

根据父类创建子类,子类 继承 父类中所有变量和方法

数据成员

示例:

class Student:      #定义类
pass
s=Student() #创建对象(类的实例化)
s.i=12345 #创建或修改类的数据成员
print(s.i) #访问类的数据成员

结果:

12345

解释:

使用关键字class定义一个类
类名为Student,通常类名首字母大写。
对象名为s
i 为数据成员
访问类中成员的语法:对象名.成员名

每个对象都有单独的内存空间去存储自己的普通数据成员(后面会讲到静态数据成员,就不一样了)

方法

类中的函数称为方法
方法可以访问此类所有的数据成员和方法。

示例:

class Student:
def f(self): #定义方法
print("hello world")
s=Student() #创建对象(类的实例化)
s.f() #调用类的方法

结果:

hello world

解释:

f 为方法名
访问类中成员的语法:对象名.成员名
类的方法与普通的函数区别:第一个参数为self。
self实际上是对象的地址。所以通过self访问的成员都属于当前对象。

带有参数的方法:

class Student:
def f(self,s): #定义方法
print(s)
s=Student()
s.f("hello world") #调用类的方法 (输出:hello world)

解释:

字符串hello world将传给s

self

示例:

class Student:
def f(self):
print(self.i) #访问类中的属性
s=Student()
s.i=12345
s.f()

结果:

12345

解释:

类的方法与普通的函数区别:第一个参数为self。
self实际上是对象的地址。
每一个对象的self地址都不一样,它们都指向本身。
通过self可以访问自身的数据成员和方法。

访问数据成员和方法必须使用self,否则就是临时变量,而不是数据成员

示例:

class Student:
def f(self):
i=200 #临时变量
print(self.i) #数据成员
print(i)
s=Student()
s.i=100 #创建类的普通数据成员
s.f()

结果:

100
200

解释:

通过结果可以看出,两个i是不同的变量
通过self访问的是对象内部的内存空间,是当前对象的成员。

构造方法

构造方法:创建对象时自动调用此方法

class Student:
def __init__(self):
print("对象被创建")
s=Student()

结果:

对象被创建

数据成员

普通数据成员

普通数据成员存储在对象自己的内存空间中。
所以每个对象的普通数据成员都是独立的,因为它们的内存空间不一样。

示例:

class Student:
def f(self):
print(self.i) #在类中访问普通数据成员
s=Student()
s.i=100 #创建类的普通数据成员
s.i=200 #修改类的普通数据成员
print(s.i) #访问类的普通数据成员
s.f()

解释:

当数据成员不存在时, s.i=100将创建此数据成员

当数据成员存在时,s.i=100将修改此数据成员

self是对象的地址,用于访问对象自己的属性,包括数据成员和方法

一般在构造函数中创建普通数据成员

在构造函数中创建普通数据成员:

class Student:
def __init(self):
self.a=1 #定义普通数据成员
self.b=2 #定义普通数据成员

解释:

当创建对象时会自动调用构造方法,所以数据成员也被自动创建。
若不使用构造方法,需要在手动的、依次给每一个对象创建这些数据成员。(很麻烦)

静态数据成员

静态数据成员存储在类中,是所有对象共享的。
通过类名访问静态成员,而不是对象名。

示例:

class Student:
name="张三"
print(Student.name) #访问静态数据成员
Student.name="李四" #修改静态数据成员

解释:

静态数据成员在类中直接定义
通过类名访问静态数据成员,因为是共享的
通过对象名访问普通数据成员,因为每个对象之间是独立的

注意:也可以通过对象名访问静态数据成员,但不建议这样

class Student:
name="张三"
s1=Student()
s2=Student() print("----创建之前:----")
print("Student.name :",Student.name)
print("s1.name :",s1.name) print("----创建之后:----")
s1.name="李四"
print("Student.name :",Student.name)
print("s1.name :",s1.name)

结果:

----创建之前:----
Student.name : 张三
s1.name : 张三
----创建之后:----
Student.name : 张三
s1.name : 李四

解释:

可以看到,当没有创建普通数据成员时:s1.name表现为静态数据成员

当创建普通数据成员后:
s1.name表现为普通数据成员

得出结论:不建议用对象名去修改静态数据成员

私有数据成员

私有数据成员只能被当前类所访问,外部和子类中都无法访问。
这样做的是为了数据和代码安全。

示例:

class Student:
__name="张三" #创建类的静态私有数据成员
def __init__(self):
self.__age=18 #创建私有数据成员
s=Student()

解释:

若在类的外部访问类的私有成员,则会报错:AttributeError。
私有数据成员名:使用双下划线开头。
静态私有数据成员:私有的,所有对象共享的通过类名访问

外部和子类中都无法访问私有成员,那如何访问它们呢?借助类中非私有方法作为桥梁

class Student:
def __init__(self):
self.__name="张三"
def getName(self): #通过此方法访问静态成员__name
return self.__name
def setName(self,name): #通过此方法修改静态成员__name
self.__name=name
s=Student()
s.setName("李四")
print(s.getName()) #输出:李四

解释:

无法直接访问私有数据成员
类的内部可以访问私有数据成员。如非私有方法。
得出结论:通过非私有方法间接访问私有数据成员。

特殊的数据成员

这些特殊的数据成员已经存在,无需自己创建
如__dict__将会返回类中所有的数据成员,以字典返回

class Student:
def __init__(self):
self.a=1
self.b=2
s=Student()
print(s.__dict__) #输出{'a': 1, 'b': 2}

方法

普通方法

class Student:
def show(self,s):
print("我是"+s)
s=Student()
s.show("学生") #输出:我是学生

私有方法

在类的外部和子类中无法访问私有方法
私有方法仅供内部使用
私有方法名用双下划线开头

class Student:
def __show(self): #外部无法直接访问
print("Private")
s=Student()
s.__show() #外部无法访问私有方法,报错!!!!

静态方法

静态方法是共享的,属于类,而不是某个对象
静态方法只能访问静态数据成员

class Student:
@classmethod
def show(cls,s):
print(cls,s) #输出类名
Student.show("张三") #输出:<class '__main__.Student'> 张三

解释:

方法前的@classmethod表示:此方法为静态方法

与普通方法类似,有一个额外的参数cls,cls是class的缩写,代表类的地址。

因为静态方法是共享的,所以通过类名调用静态方法。

构造方法

创建对象时Python自动调用构造方法

通常在构造方法中做对象的初始化工作,如创建数据成员。

构造方法名固定为__init__。

class Student:
def __init__(self):
self.name=""
self.age=0
s=Student()

析构方法

回收对象时Python自动调用析构方法
通常在析构方法中做对象的收尾工作,如关闭打开的文件。

class Student:
def __del__(self):
print("对象已被删除")
s=Student()
对象已被删除

解释:

析构方法名固定为__del__。

程序运行完毕时会回收所有变量和内存空间,所以会删除对象s。

除此之外,代码块运行完毕也会回收临时变量,如函数中的临时变量。

__call__方法

__call__方法:对象名可以当作方法名使用,调用__call__方法的函数体和形参

class Student:
def __call__(self):
print("调用__call__")
s=Student()
s() #输出:调用__call__

解释:

可以看到__call__方法的调用方式不是s.__call__(),而是通过对象名调用s()

强制转换

通过定义强制转换的方法,可以将对象转换成任意数据类型。

class Student:
def __int__(self):
return 18
s=Student()
a=int(s) #a的值为18

解释:

若要转换为int,需要定义__int__方法
强制转换的语法为int(obj)

若要转换为其他类型,如float,需要定义__float__方法。

应用-得到学生的成绩
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
def __int__(self):
return self.age
s=Student("张三",20)
a=int(s) #得到学生s的年龄
应用-得到学生的信息
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return "我是一名学生,姓名:%s,年龄:%d"%(self.name,self.age)
s=Student("张三",20)
print(s) #直接输出,就会调用str(obj)

结果:

我是一名学生,姓名:张三,年龄:20

解释:

类似的还有float等数据类型,也都可以做强制转换
若要转换为其他类型,如float,需要定义__float__方法。

运算符重载

对象之间可以进行加减乘除等操作,如:

s1=Student()
s2=Student()
s3=s1-s2

那s3的值到底是多少?到底是s1和s2身高差?还是平均分差?还是其他属性的差值?
这需要我们自己来定义,进行运算符的重载。

示例-重载符号+:

class Student:
def __init__(self,name,age):
self.name=name
self.age=age
def __add__(self,other): #运算符重载
return self.age + other.age
s1=Student("张三",20)
s2=Student("李四",18)
print(s1+s2) #输出38 (20+18=38)

解释:

重载符号+的方法名固定为:add
参数固定为self和other,分别表示左操作数和右操作数。
通过return得到结果。

常用的符号与方法名

符号 方法名 描述
+ __add__
- __sub__
* __mul__
/ __truediv__
// __floordiv__ 整除
% __mod__ 取模
** __pow__
下标运算符重载

通过下标运算符,可通过obj[n]这种形式访问对象中的数据

示例-通过下标查询:

class Student:
def __init__(self,name,age):
self.name=name
self.age=age
def __getitem__(self, item): # 使用obj[n]时调用
if type(item) == slice: #切片
print(item.start) #开始下标
print(item.stop) #结束下标
print(item.step) #步长
return item
s1=Student("张三",20)
print(s1[1:8:7])

结果:

1
8
7
slice(1, 8, 7)

示例-通过下标修改:

class Student:
def __init__(self):
self.score={"语文":98,"数学":96}
def __setitem__(self, key, value):
self.score[key]=value
s1=Student()
s1["语文"]=100
print(s1.score)

结果:

{'语文': 100, '数学': 96}

示例-通过下标删除:

class Student:
def __init__(self):
self.score={"语文":98,"数学":96}
def __delitem__(self, key):
del self.score[key]
s1=Student()
del s1["语文"]
print(s1.score)

结果:

{'数学': 96}

属性

通过定义属性,可以把函数变成数据成员

示例:

class Student:
@property
def name(self): #调用方式print(obj.name)
return "张三"
@name.setter
def name(self, value): #调用方式obj.name="Fei"
print(value)
@name.deleter
def name(self): #调用方式del obj.name
print("del name")
s=Student()
print(s.name) #输出:张三
s.name="李四" #输出:李四
del s.name #输出:del name

解释:

使用@property将函数变成数据成员
name.setter:name()的set函数
name.deleter:name()的del函数
属性就像数据成员一样使用,实际上是函数


继承

当我们想为某个类添加新的方法时,无需重新定义所有方法,使用继承即可。
例如:普通学生可以得到成绩信息,艺术生还能得到艺术成绩。

好处:

代码重用,方便维护。
通过继承,可以得到所有父类的方法,不必再复制一份代码。

基类&派生类

已存在的类称为基类(父类),新建的类称为派生类(子类)。

注意点:

子类不能直接访问父类的私有成员

示例:

class A:
def show(self):
print("我是函数show()")
class B(A): #继承了A
pass
b=B()
b.show() #因为B继承了A,所以b拥有函数show()

解释:

C继承了A和B,所以拥有A和B的所有方法
子类不能直接调用父类的私有成员

多重继承

子类可以再被继承。
如:A被B继承,B又被C继承。

class A:
pass
class B(A): #继承了A
pass
class C(B): #继承了B
pass
c=C()

函数重写

继承父类的函数之后,可以设置同名函数,这是新函数会把旧函数覆盖。

class A:
def show(self):
print("我是A")
class B(A):
def show(self): #重写了show函数
print("我是B")
b=B()
b.show() #输出:我是B

06-Python类与对象的更多相关文章

  1. python类与对象各个算数运算魔法方法总结

    1.python类与对象各个算术运算魔法方法总结: 2.各个魔法方法应用举例: 3.实例训练: (1)我们都知道在 Python 中,两个字符串相加会自动拼接字符串,但遗憾的是两个字符串相减却抛出异常 ...

  2. python 类和对象的属性

    python类和对象的属性分为类属性和对象属性两大类,类属性属于类,而对象属性属于对象. 1. 父类的对象属性会被子类的对象继承. 2. 父类的类属性会被子类继承,还是作为类属性,如果父类改变了类属性 ...

  3. 一文讲全了Python 类和对象内容

    摘要:这是一个关于 Python 类和对象的全部内容. 本文分享自华为云社区<从零开始学python | Python 类和对象-面向对象编程>,原文作者:Yuchuan  . Pytho ...

  4. python类、对象

    python类.对象 学习完本篇,你将会深入掌握 什么是类,对象 了解类和对象之间的关系 能独立创建一个People(人类),属性有姓名.性别.年龄.提供一个有参的构造方法,编写一个show方法,输出 ...

  5. python 类、对象、方法、属性

    在python中,一个对象的特征也称为属性(attribute).它所具有的行为也称为方法(method) 结论:对象=属性+方法 在python中,把具有相同属性和方法的对象归为一个类(class) ...

  6. python类、对象、方法、属性之类与对象笔记

    python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,坐着的椅子就是对象,家里养的小狗也是一个对象...... 我们通过描述属性(特征)和行为来描述一个对象的.比如家里的小狗, ...

  7. python类与对象基本语法

    面向对象编程的2个非常重要的概念:类和对象. 对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念--类. 类就相当于制造飞机时的图纸,用它 ...

  8. python 类和对象

    类和对象 类 1.类的组成    数据和函数,二者是类的属性 2.两个作用: 实例化 属性引用  属性引用:类名.属性(增删改查)   实例化: 类名加括号就是实例化,会自动出发__init__的运行 ...

  9. Python类和对象

    目录 类与对象 其他方法 继承 经典类和新式类 派生 组合 接口.归一化设计与抽象类 继承实现的原理 子类中调用父类的方法 指名道姓 super()方法 多态与多态性 封装 单下划线开头 双下划线开头 ...

  10. python类与对象的组合与继承

    1.把类的对象实例化放到一个新的类里面叫做类的组合,组合就是指几个横向关系的类放在一起,纵向关系的类放在一起是继承,根据实际应用场景确定.简单的说,组合用于“有一个”的场景中,继承用于“是一个”的场景 ...

随机推荐

  1. gitlab-ce-15.9.4安装

    如果需要汉化版本,请根据汉化来选择版本 汉化包下载地址:https://gitlab.com/xhang/gitlab/ 1.依赖包安装 yum -y install policycoreutils- ...

  2. Linux 环境下制作 deb 软件包

    一.简介 前面的笔记中已经展示过了,怎么移植的一个工具境到 ARM 环境中,对于使用 buildroot 和 yocto 的朋友来说,此笔记就没有作用了,因为管理工具包会帮我们把这个工作处理了,就算需 ...

  3. tomcat(2)- tomcat目录结果和配置文件

    目录 1 Tomcat目录结构 2 Tomcat的配置文件 2.1 server.xml配置文件 2.2 server.xml配置文件结构 2.3 WEB应用自动部署 2.4 配置文件各个组件的关联 ...

  4. nim 4. 模块

    看了一下nim的模块系统,真的非常简洁. 1) 一个nim文件就是一个模块 2) 通过import 引入模块,引入的时候不需要带扩展名, 比如有个模块 mod1.nim,  引入的时候: import ...

  5. Unity Visual Scripting 使用随记

    1.Wait Until并不会再执行前面的代码,而是反复执行获取bool变量的代码:需自己拆出来写. 2.yield return null对应Wait For Next Frame,多用这个避免协程 ...

  6. 学习c# 7.0-7.3的ref、fixed特性并在Unity下测试

    1.ref的一些运用 1.1 ref readonly 关于ref,一个主要应用是防止结构体拷贝,若返回的结构体不需要修改则用ref readonly,类似c++的const标记 : private ...

  7. 密码学—Vigenere破解Python程序

    文章目录 概要 预备知识点学习 整体流程 技术名词解释 技术细节 小结 代码 概要 破解Vigenere需要Kasiski测试法与重合指数法的理论基础 具体知识点细节看下面这两篇文章 预备知识点学习 ...

  8. 2024-05-22:用go语言,你有一个包含 n 个整数的数组 nums。 每个数组的代价是指该数组中的第一个元素的值。 你的目标是将这个数组划分为三个连续且互不重叠的子数组。 然后,计算这三个子数

    2024-05-22:用go语言,你有一个包含 n 个整数的数组 nums. 每个数组的代价是指该数组中的第一个元素的值. 你的目标是将这个数组划分为三个连续且互不重叠的子数组. 然后,计算这三个子数 ...

  9. CSS置顶操作(z-index属性)

    z-index使用方法: 1.首先要把position设置为 absolute 或 relative 或 fixed,z-index才能生效 2.设置z-index的值(整数) # 值越大代表越置前, ...

  10. 20220314线上panic总结

    panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentatio ...