Python基础day08【面向对象(类、对象、属性)、魔方方法(init、str、del、repr)】
- 视频、源码、课件、软件、笔记:超全面Python基础入门教程【十天课程】博客笔记汇总表【黑马程序员】
目录
0、复习
1、类外部添加和获取对象属性
2、类内部操作属性
3、魔法方法
3.1、__init__()[掌握]
3.1.1、单参__init__()
3.1.2、多参__init__()
3.2、__str__()[掌握]
3.3、__del__()[理解]
4、案例:烤地瓜
烤地瓜-调料版
5、补充:查看对象的引用计数
6、案例:搬家具
打印家具信息
7、区分__str__()与__repr__()
8、附录:魔方方法(__str__对比__repr__)
8.1、引言
8.2、分析
8.2.1、重写__str__()方法
8.2.2、重写__repr__()方法
8.3、总结
9、总结
0、复习
二进制文件的读写,不需要指定encoding参数。
基础班考试:单选、多选、代码题。
while True: pass 使用场景:在书写代码的时候,不确定循环一共执行多少次,即不知道循环在什么时候结束(具体结束的时间),在运行代码的过程中才能确定,在代码中进行if判断,如果条件不满足,就使用break终止循环。
my_list = list() # 创建列表类对象
my_dict = dict() # 创建字典类对象
my_tuple = tuple() # 创建元组类对象class 类名(object):
def 函数名(self):
pass
1、类外部添加和获取对象属性
每个对象,会保存自己的属性值,不同对象的属性值之间没有关联。
class Dog(object):def play(self):print('小狗快乐的拆家中...')# 创建对象
dog1 = Dog()
dog1.play() # 小狗快乐的拆家中...# 给对象添加属性:对象.属性名 = 属性值
dog1.name = '大黄' # 给dog对象添加name属性,属性值是大黄
dog1.age = 2 # 给dog对象添加age属性,属性值是2# 获取对象的属性值:对象.属性名
print(dog1.name) # 大黄
print(dog1.age) # 2# 修改属性值和添加一样,存在就是修改;不存在就是添加
dog1.age = 3 # age属性已经存在,所以是修改属性值
print(dog1.age) # 3dog2 = Dog() # 新创建一个对象dog2
dog2.name = '小白'
print(dog2.name) # 小白
2、类内部操作属性
self 就是一个形参的名字,可以写成其他的形参名,一般不修改这个名字,默认是self。
class Dog(object):# self作为类中方法的第一个形参,在通过对象调用方法的时候,不需要手动地传递实参值,# 是python解释器自动将调用该方法的对象传递给self, 所以self这个形参代表的是对象def play(self):print(f'self: {id(self)}')print(f'小狗 {self.name} 在快乐地拆家中...')# 创建对象
dog1 = Dog()
dog1.name = '大黄'
print(f"dog : {id(dog1)}")
dog1.play()
print('-------------------------')
dog2 = Dog()
dog2.name = '小白'
print(f"dog2: {id(dog2)}")
dog2.play()
3、魔法方法
在 python 的类中有一类方法,这类方法以`两个下划线开头`和`两个下划线结尾`,并且在`满足某个特定条件的情况下,会自动调用`。这类方法,称为魔法方法。
如何学习魔法方法:1.魔法方法在什么情况下会自动调用;2.这个魔法方法有什么作用;3.这个魔法方法有哪些注意事项。
3.1、__init__()
[掌握]
调用时机:在创建对象之后,会立即调用。类似于Java中的构造方法。
作用:
1.用来给对象添加属性,给对象属性一个初始值(构造函数);
2.代码的业务需求,每创建一个对象,都需要执行的代码可以写在`__init__ `中。注意点:如果`__init__`方法中,有除了 self 之外的形参,那么在创建的对象的时候,需要给额外的形参传递实参值`类名(实参)`。
3.1.1、单参__init__()
class Dog(object):def __init__(self): # self是对象print('我是__init__方法,我被调用了!')# 对象.属性名 = 属性值self.name = '小狗'# 创建对象
Dog() # 我是__init__方法,我被调用了!dog1 = Dog() # 我是__init__方法,我被调用了!
print(dog1.name) # 小狗dog2 = Dog() # 我是__init__方法,我被调用了!
print(dog2.name) # 小狗
3.1.2、多参__init__()
class Dog(object):def __init__(self, name): # self是对象print('我是__init__方法,我被调用了!')# 对象.属性名 = 属性值self.name = namedef play(self):print(f"小狗{self.name}快乐地拆家中...")# 创建对象 类名(实参值)
dog1 = Dog('大黄') # 我是__init__方法,我被调用了!
print(dog1.name) # 大黄
dog1.play() # 小狗大黄快乐地拆家中...dog2 = Dog('小白') # 我是__init__方法,我被调用了!
print(dog2.name) # 小白
dog2.play() # 小狗小白快乐地拆家中...
3.2、__str__()
[掌握]
调用时机:
1.`print(对象)`,会自动调用`__str__`方法,打印输出的结果是`__str__`方法的返回值;
2.`str(对象)`类型转换,将自定义对象转换为字符串的时候,会自动调用。应用:
1.打印对象的时候,输出一些属性信息;
2.需要将对象转换为字符串类型的时候。注意点:`方法必须返回一个字符串`,只有 self 一个参数。
class Dog(object):def __init__(self, name, age):# 添加属性self.name = nameself.age = agedef __str__(self):print('我是__str__, 我被调用了...')# 必须返回一个字符串return f"小狗的名字是{self.name}、年龄是{self.age}。"# 创建对象
dog = Dog('大黄', 2)
print(dog) # 没有定义__str__方法,print(对象)默认输出对象的引用地址 # <__main__.Dog object at 0x0000020F33D574C0>str_dog = str(dog) # 没有定义__str__方法,类型转换,赋值的也是引用地址
print(str_dog) # <__main__.Dog object at 0x0000020F33D574C0>
3.3、__del__()
[理解]
__del__()析构函数。调用时机:对象在内存中被销毁删除的时候(引用计数为 0)会自动调用__del__方法。
1.程序代码运行结束,在程序运行过程中,创建的所有对象和变量都会被删除销毁;
2.使用`del 变量`,将这个对象的引用计数变为 0。会自动调用 __del__ 方法。应用场景:对象被删除销毁的时候,要书写的代码可以写在`__del__`中,一般很少使用。
引用计数:是python内存管理的一种机制,是指一块内存,有多少个变量在引用:
1. 当一个变量,引用一块内存的时候,引用计数加 1;
2. 当删除一个变量,或者这个变量不再引用这块内存,引用计数减 1;
3. 当内存的引用计数变为 0 的时候,这块内存被删除,内存中的数据被销毁。my_list = [1, 2] # 1
my_list1 = my_list # 2
del my_list # 1
del my_list1 # 0
class Dog(object):def __init__(self, name, age):# 添加属性self.name = nameself.age = agedef __str__(self):# 必须返回一个字符串return f"小狗的名字是{self.name}, 年龄是{self.age}!"def __del__(self):print(f'我是__del__ 方法, 我被调用了, {self.name}被销毁了...')# 创建一个对象
# dog = Dog('大黄', 2)
# dog1 = Dog('小白', 1)dog = Dog('小花', 3) # 小花 引用计数为1
dog2 = dog # 小花 引用计数2
print('第一次删除之前。')
del dog # dog变量不能使用了, 小花对象引用计数变为1
print('第一次删除之后。')
print('第二次删除之前。')
del dog2 # dog2变量不能使用, 小花对象的引用计数变为0, 会立即__del__方法
print('第二次删除之后。')
4、案例:烤地瓜
封装的小套路:
1.根据文字的描述信息确定对象,对象有什么,就是属性;
2.根据文字的描述信息,对象能干什么,就是方法;
3.根据文字的描述信息,确定方法怎么书写。
烤地瓜规则:
- 地瓜有自己的状态,默认是生的,地瓜可以进行烧烤。
- 地瓜有自己烧烤的总时间,由每次烧烤的时间累加得出。
- 地瓜烧烤时,需要提供本次烧烤的时间。
- 地瓜烧烤时,地瓜状态随着烧烤总时间的变化而改变:[0,3) 生的、[3,6) 半生不熟、[6,8) 熟了、>=8 烤糊了。
- 输出地瓜信息时,可以显示地瓜的状态和烧烤的总时间。
类名:地瓜类 Potato
属性:
状态 status='生的'
烧烤总时间 total_time = 0
方法:
def cook(self, 烧烤时间):
计算烧烤的总时间
修改地瓜的状态的
pass
输出信息 __str__()
定义属性 __init__()
class Potato(object):def __init__(self):self.status = '生的'self.total_time = 0def cook(self, time):# 计算总时间self.total_time += time# 修改地瓜的状态if self.total_time < 3:self.status = '生的'elif self.total_time < 6:self.status = '半生不熟的'elif self.total_time < 8:self.status = '熟了'else:self.status = '烤糊了'def __str__(self):return f"地瓜的状态<<{self.status}>>, 烧烤总时间为<{self.total_time}>"# 创建对象
potato = Potato()
print(potato) # 地瓜的状态<<生的>>, 烧烤总时间为<0>potato.cook(4)
print(potato) # 地瓜的状态<<半生不熟的>>, 烧烤总时间为<4>potato.cook(3)
print(potato) # 地瓜的状态<<熟了>>, 烧烤总时间为<7>
烤地瓜-调料版
属性:调料: name_list = []
方法:添加调料 add()
class Potato(object):def __init__(self):self.status = '生的'self.total_time = 0self.name_list = [] # 保存调料的列表def cook(self, time):# 计算总时间self.total_time += time# 修改地瓜的状态if self.total_time < 3:self.status = '生的'elif self.total_time < 6:self.status = '半生不熟的'elif self.total_time < 8:self.status = '熟了'else:self.status = '烤糊了'def __str__(self):# buf_list = str(self.name_list) # str([]) ===> '[]'# buf_list = buf_list.replace('[', '')# 字符串.join(列表):将字符串添加到列表中的每个元素之间,组成新的字符串。buf = ','.join(self.name_list) # 将列表中的字符串组成一个大的字符串if self.name_list:return f"地瓜的状态<<{self.status}>>, 烧烤总时间为<{self.total_time}>, 已添加的调料有: {buf}!"else:return f"地瓜的状态<<{self.status}>>, 烧烤总时间为<{self.total_time}>, 还没有添加调料!"def add(self, name): # 添加调料的方法self.name_list.append(name)# 创建对象
potato = Potato()
print(potato) # 地瓜的状态<<生的>>, 烧烤总时间为<0>, 还没有添加调料!potato.add('油')
potato.cook(4)
potato.add('辣椒面')
print(potato) # 地瓜的状态<<半生不熟的>>, 烧烤总时间为<4>, 已添加的调料有: 油,辣椒面!potato.cook(3)
potato.add('孜然')
print(potato) # 地瓜的状态<<熟了>>, 烧烤总时间为<7>, 已添加的调料有: 油,辣椒面,孜然!
5、补充:查看对象的引用计数
import sysclass Dog(object):passdog = Dog() # 1
print(sys.getrefcount(dog)) # 2 显示的时候,会比实际的多一个dog1 = dog # 2
print(sys.getrefcount(dog)) # 3 显示的时候,会比实际的多一个del dog # 1
print(sys.getrefcount(dog1)) # 2 显示的时候,会比实际的多一个
6、案例:搬家具
搬家具规则:
- 家具分不同的类型,并占用不同的面积。
- 输出家具信息时,显示家具的类型和家具占用的面积。
- 房子有自己的地址和占用的面积。
- 房子可以添加家具,如果房子的剩余面积可以容纳家具,则提示家具添加成功;否则提示添加失败。
- 输出房子信息时,可以显示房子的地址、占地面积、剩余面积。
类名:家具类 Furniture
属性:
类型 name
面积 area
方法:
输出家具信息 __str__
定义属性 __init__
--------------------------------------------
类名:房子类 House
属性:
地址 address
面积 h_area
家具列表 furniture_list = []
方法:
添加家具 add_furniture()
输出房子信息 __str__
定义属性 __init__
# 定义家具类 Furniture 类
class Furniture(object):def __init__(self, name, area):# 类型self.name = name# 面积self.area = areadef __str__(self):return f'家具的类型<{self.name}>, 占地面积<{self.area}>平。'# 定义房子类
class House(object):def __init__(self, address, area):self.address = addressself.h_area = areaself.furniture_list = []self.free_area = area # 房子的剩余面积def add_furniture(self, obj_furniture):""" 添加家具 obj_furniture: 家具类的对象"""if self.free_area > obj_furniture.area:self.furniture_list.append(obj_furniture)# 修改剩余面积self.free_area -= obj_furniture.areaprint(f'家具<{obj_furniture.name}>添加成功。')else:print('添加失败,换个大房子吧。')def __str__(self):return f"房子的地址为<{self.address}>, 占地面积为<{self.h_area}>, 剩余面积为{self.free_area}。"# 创建家具对象
bed = Furniture('豪华双人床', 15)
print(bed)# 创建一个房子类对象
house = House('意大利农场', 100)
print(house)
house.add_furniture(bed)
print(house)
打印家具信息
# 定义家具类 Furniture 类
class Furniture(object):def __init__(self, name, area):# 类型self.name = name# 面积self.area = areadef __str__(self):return f'家具的类型<{self.name}>, 占地面积<{self.area}>平。'# 定义房子类
class House(object):def __init__(self, address, area):self.address = addressself.h_area = areaself.furniture_list = []self.free_area = area # 房子的剩余面积def add_furniture(self, obj_furniture):""" 添加家具 obj_furniture: 家具类的对象"""if self.free_area > obj_furniture.area:self.furniture_list.append(obj_furniture)# 修改剩余面积self.free_area -= obj_furniture.areaprint(f'家具<{obj_furniture.name}>添加成功。')else:print('添加失败,换个大房子吧。')def __str__(self):# 自定义家具类,将该类的对象添加到列表中(容器), 直接打印列表,显示的是自定义对象的引用地址# [家具对象, 家具对象, ... ] ---> [家具类型, 家具类型, ...]if self.furniture_list:buf_list = [obj.name for obj in self.furniture_list]return f"房子的地址为<{self.address}>, 占地面积为<{self.h_area}>, 剩余面积为{self.free_area}, " \f"家具有<{','.join(buf_list)}>。"else:return f"房子的地址为<{self.address}>, 占地面积为<{self.h_area}>, 剩余面积为{self.free_area}, " \f"还没有购买家具。"# 创建家具对象
bed = Furniture('豪华双人床', 15)
print(bed)# 创建一个房子类对象
house = House('意大利农场', 100)
print(house)house.add_furniture(bed)
print(house)sofa = Furniture('柔软大沙发', 8)
print(sofa)house.add_furniture(sofa)
print(house)
7、区分__str__()与__repr__()
my_list = ['hello', 'python', 'cpp'] # 列表中存储了三个字符串对象
print(my_list) # ['hello', 'python', 'cpp']class Dog(object):def __init__(self, name, age):self.name = nameself.age = agedef __str__(self):return f'{self.name}, {self.age}'def __repr__(self):"""repr方法和str方法,非常类似,也是必须返回一个字符串!"""return f"{self.name}"# 将三个Dog类的对象添加到列表中
my_list1 = [Dog('大黄', 2), Dog('小白', 4), Dog('小花', 6)]
print(my_list1) # [大黄, 小白, 小花]dog = Dog('大黄', 2)
print(dog) # __str__ 大黄, 2
8、附录:魔方方法(__str__对比__repr__)
python中的魔法方法:`__str__` 和`__repr__`.pdf
8.1、引言
在学习⾯向对象的时候,我们知道在 python 中有⼀类特殊的⽅法,叫做魔法⽅法,这种⽅法的特点如下:
1. ⽅法定义的时候以两个下划线开头和两个下划线结尾:如__init__ 、 __str__ 和__repr__;
2. 这类⽅法⼀般不需要我们⼿动调⽤,在满⾜某个条件的时候会⾃动调⽤,这个满⾜的条件我们可以称为调⽤时机。在Python中有两个魔法⽅法都是⽤来描述对象信息的,__str__和__repr__,那为什么要定义两个这样的⽅法呢,其实是它们设计的⽬的是不⼀样的:
1.__repr__的⽬标是准确性,或者说,__repr__的结果是让解释器⽤的;
2.__str__的⽬标是可读性,或者说,__str__的结果是让⼈看的。
8.2、分析
那下边,我们详细地来看⼀下,他们的⽤法:在不重写__str__和__repr__的情况下,打印对象的 输出结果不太友好,是对象的内存地址,即 id的结果。
class Person(object): # 定义 Person 类def __init__(self, name):self.name = namep = Person("isaac")# 以下为测试输出的结果:
print(p) # <__main__.Person object at 0x0000016FB4E0E220>
p # <__main__.Person object at 0x0000016FB4E0E220>
p.__str__() # '<__main__.Person object at 0x0000016FB4E0E220>'
p.__repr__() # '<__main__.Person object at 0x0000016FB4E0E220>'
这样的输出结果,并不是我们想要的结果,此时我们重写__str__和__repr__⽅法。
8.2.1、重写__str__()方法
class Person(object): # 定义 Person 类def __init__(self, name):self.name = namedef __str__(self):return "__str__ ⽅法 " + self.namep = Person("isaac")# 以下为测试输出的结果:
print(p)
str(p)
f"{p}"
p.__str__()
p
此时我们发现在使⽤ print 打印对象、对象的格式化输出以及调⽤str⽅法,调⽤的都是__str__⽅法。但在交互环境下,直接输出对象的时候,没有调⽤__str__⽅法,输出的结果仍然是id的结果。
8.2.2、重写__repr__()方法
class Person(object): # 定义 Person 类:def __init__(self, name):self.name = namedef __str__(self):return "__str__ ⽅法 " + self.namedef __repr__(self):return "__repr__ ⽅法 " + self.namep = Person("isaac")# 以下为测试输出的结果:
p
p.__repr__()
print(p)
通过简单的对⽐,我们发现,在交互环境下,直接输出对象,调⽤的__repr__⽅法。
另外还需要注意的是,如果将对象放在容器中进⾏输出,调⽤的是__repr__⽅法。
8.3、总结
Python 中的__str__和__repr__⽅法都是⽤来显示的,即描述对象信息的。
1.__str__的⽬标是可读性,或者说,__str__的结果是让⼈看的。主要⽤来打印,即print操作,
2.__repr__的⽬标是准确性,或者说,__repr__的结果是让解释器⽤的。__repr__⽤于交互模式下提示回应,
3.如果没有重写__str__⽅法,但重写了__repr__⽅法时,所有调⽤__str__的时机都会调⽤__repr__⽅法。
9、总结
Python基础day08【面向对象(类、对象、属性)、魔方方法(init、str、del、repr)】相关推荐
- Python训练营—Tesk3—Python基础进阶—从函数到高级魔方方法
Python基础进阶--从函数到高级魔方方法 目录 Python基础进阶--从函数到高级魔方方法 一.函数 1.函数的定义 2.函数的调用 3.函数参数 4.变量作用域 ...
- 语法基础(三. 类,属性,方法,方法重载,方法重写,构造方法,访问修饰符)
语法基础(三. 类,属性,方法,方法重载,方法重写,构造方法,访问修饰符) (如有错误,欢迎指正,感谢!) 类 类是面向对象的程序设计中的概念,实现信息的封装 概念: 类就是拥有相等行为和相同的属性的 ...
- ASP.NET基础教程-DataTable类对象-属性方法和事件
DataTable类对象可以表示表格,也可以在DataSet中存储多个DataTable对象. 该对象的属性方法和事件列表如下: 转载于:https://blog.51cto.com/chenxing ...
- python学习高级篇(part10)--类对象的特殊方法和特殊属性
学习笔记,仅供参考,有错必纠 文章目录 python 学习高级篇 类对象的特殊方法之`__del__()` 类对象的特殊方法之`__getattr__()` 类对象的特殊方法之`__getitem__ ...
- python学习高级篇(part8)--类对象的特殊方法
学习笔记,仅供参考,有错必纠 文章目录 python 学习高级篇 类对象的特殊方法之`__iter__()`和`__next__()` 类对象的特殊方法之`__add__()`和`__radd__() ...
- python用来初始化对象属性的是_猪行天下之Python基础——8.1 类与对象
内容简述: 1.面相对象的理解 2.类与对象 3.继承 4.组合 5.对象相关的内置函数 1.面相对象的理解 考虑到部分读者可能没有接触过面向对象编程,所以先介绍下面向对象的一些特征,形成一个面向对象 ...
- Python基础:面向对象基础 (一) 类及其属性和魔法方法
定义类,添加和获取对象属性 # 定义类 格式如下 # class 类名: # 方法列表# 新式类定义形式 # info 是一个实例方法,第一个参数一般是self,表示实例对象本身 class Hero ...
- Python基础day08 作业解析【7道 面向对象题目】
视频.源码.课件.软件.笔记:超全面Python基础入门教程[十天课程]博客笔记汇总表[黑马程序员] Python基础day08[面向对象(类.对象.属性).魔方方法(init.str.del.rep ...
- python学习——oop-python面向对象,类相关基础
0.目录 文章目录 0.目录 1. 面向对象概述(ObjectOriented, OO) 2. 类的基本实现 3. 关于self 4.类相关函数 5.类的成员描述符(属性) 6.类的内置属性 7.类的 ...
- python查看类的属性和方法_Python 获取对象的属性和方法—dir 函数
工作中,我们使用一些之前没用到过的模块,使用时需要了解一下这个模块中的一些类的方法或属性,怎么做呢?目前我比较常用的两款IDE"Pycharm"和"VSCode" ...
最新文章
- java注册用户代码_java用户管理注册功能 含前后台代码
- 微盘 计算机英语,高中英语,微盘.doc
- 【转】ORM系列之Entity FrameWork详解
- 树(5)-----判断两颗树一样或者一棵树是否是另外一颗的子树
- 简记Inception系列
- python轻量级web开发框架Flask学习使用
- win7设置固定IP重启后无法上网,ipconfig显示为自动配置IPV4 169.254的地址
- stringbuffer java API_java API中Object,String,Stringbuffer,StringBuilder的总结
- 宁波保哥后院_如何抛出终极后院电影之夜
- python 拼音输入法_隐马尔科夫模型python实现简单拼音输入法
- hdu 2037 今年暑假不AC 贪心)
- 《java程序员面试笔试宝典》学习笔记
- 神经网络量化--per-channel量化
- 【GAMES101 课程小结】:Lecture 13 Ray Tracing
- 解决word转PDF文件时图片位置改变和字体格式改变的问题
- 【C语言】强符号和弱符号
- 每日一招:什么样的股票才能越跌越买
- 单元覆盖测试排除某些类烧苗_智慧树人体生理学第一单元章节测试网课答案选修课慕课答案...
- 日本交通卡-SUICA卡
- 【MySQL】增删查改(进阶)
热门文章
- nginx https 访问http_Nginx之Http模块系列之访问控制模块
- 2.控制反转 spring_ioc
- linux 内核 ntfs,Linux大脑 内核 内核编译(NTFS)
- php和dart的区别,Dart相等和关系运算符
- 二十、预处理CSS的LESS
- AAAI 2022 | 可解释和鲁棒的联合文本分类及证据提取
- Industry AI Live | BERT在美团搜索业务中的应用
- 线下课程推荐 | 知识图谱理论与实战:构建行业知识图谱 (第四期)
- CVPR2019接收结果公布了,但CVPR 2018的那些论文都怎么样了?
- 开源代码“All in One”:6 份最新「Paper + Code」等你复现 | PaperDaily #12