06-Python类与对象
什么是类
百度百科:
类是对象的抽象,对象是对客观事物的抽象。
用通俗的话来说:
类是类别的意思,是数据类型。
对象是类别下的具体事物。
也就是说:
类是数据类型,对象是变量。
比如:
自定义一种数据类型:水果。那水果就是类。
由此数据类型创建一个变量:一个苹果。那这个苹果就是对象。
类是抽象的,对象是具体的。
类和对象的关系
类是一种数据类型,相当于一个模板,用于创建对象。
每一个对象都有自己独立的内存空间,用于存储数据成员。
比如:
人都有名字,年龄,性别等信息。这是一个类,是抽象的。
小明叫张明,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类与对象的更多相关文章
- python类与对象各个算数运算魔法方法总结
1.python类与对象各个算术运算魔法方法总结: 2.各个魔法方法应用举例: 3.实例训练: (1)我们都知道在 Python 中,两个字符串相加会自动拼接字符串,但遗憾的是两个字符串相减却抛出异常 ...
- python 类和对象的属性
python类和对象的属性分为类属性和对象属性两大类,类属性属于类,而对象属性属于对象. 1. 父类的对象属性会被子类的对象继承. 2. 父类的类属性会被子类继承,还是作为类属性,如果父类改变了类属性 ...
- 一文讲全了Python 类和对象内容
摘要:这是一个关于 Python 类和对象的全部内容. 本文分享自华为云社区<从零开始学python | Python 类和对象-面向对象编程>,原文作者:Yuchuan . Pytho ...
- python类、对象
python类.对象 学习完本篇,你将会深入掌握 什么是类,对象 了解类和对象之间的关系 能独立创建一个People(人类),属性有姓名.性别.年龄.提供一个有参的构造方法,编写一个show方法,输出 ...
- python 类、对象、方法、属性
在python中,一个对象的特征也称为属性(attribute).它所具有的行为也称为方法(method) 结论:对象=属性+方法 在python中,把具有相同属性和方法的对象归为一个类(class) ...
- python类、对象、方法、属性之类与对象笔记
python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,坐着的椅子就是对象,家里养的小狗也是一个对象...... 我们通过描述属性(特征)和行为来描述一个对象的.比如家里的小狗, ...
- python类与对象基本语法
面向对象编程的2个非常重要的概念:类和对象. 对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念--类. 类就相当于制造飞机时的图纸,用它 ...
- python 类和对象
类和对象 类 1.类的组成 数据和函数,二者是类的属性 2.两个作用: 实例化 属性引用 属性引用:类名.属性(增删改查) 实例化: 类名加括号就是实例化,会自动出发__init__的运行 ...
- Python类和对象
目录 类与对象 其他方法 继承 经典类和新式类 派生 组合 接口.归一化设计与抽象类 继承实现的原理 子类中调用父类的方法 指名道姓 super()方法 多态与多态性 封装 单下划线开头 双下划线开头 ...
- python类与对象的组合与继承
1.把类的对象实例化放到一个新的类里面叫做类的组合,组合就是指几个横向关系的类放在一起,纵向关系的类放在一起是继承,根据实际应用场景确定.简单的说,组合用于“有一个”的场景中,继承用于“是一个”的场景 ...
随机推荐
- dotnet 6 通过 DOTNET_ROOT 让调起的应用的进程拿到共享的运行时文件夹
我的应用是独立发布的,在用户的设备上不需要额外去安装 .NET 运行时.但是我的应用有一个需求是下载另一个应用作为插件,由本应用调起插件进程.本文告诉大家如何解决调用插件的进程时,赋值给插件进程运行时 ...
- 迁移 dotnet 6 提示必须将目标平台设置为 Windows 平台
我在迁移一个古老的项目为 .NET 6 框架,但是 VS 提示 error NETSDK1136 如果使用 Windows 窗体或 WPF,或者引用使用 Windows 窗体或 WPF 的项目或包,则 ...
- 阿里云OSS文件上传几种方法(主要是前端)
目录 零.准备 一.服务端签名后直传 1. 阿里云控制台配置 2. 后端接口开发(PHP) 3. 前端获取签名后上传 二.使用STS临时凭证进行上传 1. 后端接口开发(node) 2. 前端获取临时 ...
- 04 Xpath_[实例]爬取maoyan
目录 Xpath lxml库的安装和使用 提取的内容 代码 生成的csv 下载的图片 参考文档 Xpath lxml库的安装和使用 提取的内容 随意选取的一段 节点包含的影片信息,如下所示: < ...
- Xcode多进程调试:WKWebView
由于WKWebView使用的是多线程架构,渲染模块和网络模块都各自在一个单独的进程里面,因此,如果需要设置渲染模块或者网络模块里面的断点,需要做一些特殊处理. 举个例子,假设在Xcode里面设置了渲染 ...
- postgresql 开启审计日志
1.审计清单说明 logging_collector --是否开启日志收集开关,默认off,推荐on log_destination --日志记录类型,默认是stderr,只记录错 ...
- leaflet 使用高德地图实例
let map = L.map("mapid", { minZoom: 10, maxZoom: 15, center: [37.005646, 114.52044], zoom: ...
- 卷爆短剧出海:五大关键,由AIGC重构
短剧高温下,谈谈AIGC的助攻路线. 短剧,一个席卷全球的高温赛道. 以往只是踏着霸总题材,如今,内容循着精品化.IP化的自然发展风向,给内容.制作.平台等产业全链都带来新机,也让短剧消费走向文化深处 ...
- Python OpenCV #1 - OpenCV介绍
一.OpenCV介绍 1.1 OpenCV-Python教程简介 OpenCV由 Gary Bradsky 于1999年在英特尔创立,第一个版本于2000年发布. Vadim Pisarevsky 加 ...
- 简单粗暴通过 Binlog 日志来恢复 MySQL 数据
引言 Binlog 日志的主要作用: 1.增量备份. 2.主从复制. 操作步骤 1.登录 MySQL -> 执行 show variables like '%log_bin%'; 查询 binl ...