• 视频、源码、课件、软件、笔记:超全面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.根据文字的描述信息,确定方法怎么书写。

烤地瓜规则:

  1. 地瓜有自己的状态,默认是生的,地瓜可以进行烧烤。
  2. 地瓜有自己烧烤的总时间,由每次烧烤的时间累加得出。
  3. 地瓜烧烤时,需要提供本次烧烤的时间。
  4. 地瓜烧烤时,地瓜状态随着烧烤总时间的变化而改变:[0,3) 生的、[3,6) 半生不熟、[6,8) 熟了、>=8 烤糊了。
  5. 输出地瓜信息时,可以显示地瓜的状态和烧烤的总时间。

类名:地瓜类 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、案例:搬家具

搬家具规则:

  1. 家具分不同的类型,并占用不同的面积。
  2. 输出家具信息时,显示家具的类型和家具占用的面积。
  3. 房子有自己的地址和占用的面积。
  4. 房子可以添加家具,如果房子的剩余面积可以容纳家具,则提示家具添加成功;否则提示添加失败。
  5. 输出房子信息时,可以显示房子的地址、占地面积、剩余面积。

类名:家具类 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)】相关推荐

  1. Python训练营—Tesk3—Python基础进阶—从函数到高级魔方方法

                    Python基础进阶--从函数到高级魔方方法 目录 Python基础进阶--从函数到高级魔方方法 一.函数 1.函数的定义 2.函数的调用 3.函数参数 4.变量作用域 ...

  2. 语法基础(三. 类,属性,方法,方法重载,方法重写,构造方法,访问修饰符)

    语法基础(三. 类,属性,方法,方法重载,方法重写,构造方法,访问修饰符) (如有错误,欢迎指正,感谢!) 类 类是面向对象的程序设计中的概念,实现信息的封装 概念: 类就是拥有相等行为和相同的属性的 ...

  3. ASP.NET基础教程-DataTable类对象-属性方法和事件

    DataTable类对象可以表示表格,也可以在DataSet中存储多个DataTable对象. 该对象的属性方法和事件列表如下: 转载于:https://blog.51cto.com/chenxing ...

  4. python学习高级篇(part10)--类对象的特殊方法和特殊属性

    学习笔记,仅供参考,有错必纠 文章目录 python 学习高级篇 类对象的特殊方法之`__del__()` 类对象的特殊方法之`__getattr__()` 类对象的特殊方法之`__getitem__ ...

  5. python学习高级篇(part8)--类对象的特殊方法

    学习笔记,仅供参考,有错必纠 文章目录 python 学习高级篇 类对象的特殊方法之`__iter__()`和`__next__()` 类对象的特殊方法之`__add__()`和`__radd__() ...

  6. python用来初始化对象属性的是_猪行天下之Python基础——8.1 类与对象

    内容简述: 1.面相对象的理解 2.类与对象 3.继承 4.组合 5.对象相关的内置函数 1.面相对象的理解 考虑到部分读者可能没有接触过面向对象编程,所以先介绍下面向对象的一些特征,形成一个面向对象 ...

  7. Python基础:面向对象基础 (一) 类及其属性和魔法方法

    定义类,添加和获取对象属性 # 定义类 格式如下 # class 类名: # 方法列表# 新式类定义形式 # info 是一个实例方法,第一个参数一般是self,表示实例对象本身 class Hero ...

  8. Python基础day08 作业解析【7道 面向对象题目】

    视频.源码.课件.软件.笔记:超全面Python基础入门教程[十天课程]博客笔记汇总表[黑马程序员] Python基础day08[面向对象(类.对象.属性).魔方方法(init.str.del.rep ...

  9. python学习——oop-python面向对象,类相关基础

    0.目录 文章目录 0.目录 1. 面向对象概述(ObjectOriented, OO) 2. 类的基本实现 3. 关于self 4.类相关函数 5.类的成员描述符(属性) 6.类的内置属性 7.类的 ...

  10. python查看类的属性和方法_Python 获取对象的属性和方法—dir 函数

    工作中,我们使用一些之前没用到过的模块,使用时需要了解一下这个模块中的一些类的方法或属性,怎么做呢?目前我比较常用的两款IDE"Pycharm"和"VSCode" ...

最新文章

  1. java注册用户代码_java用户管理注册功能 含前后台代码
  2. 微盘 计算机英语,高中英语,微盘.doc
  3. 【转】ORM系列之Entity FrameWork详解
  4. 树(5)-----判断两颗树一样或者一棵树是否是另外一颗的子树
  5. 简记Inception系列
  6. python轻量级web开发框架Flask学习使用
  7. win7设置固定IP重启后无法上网,ipconfig显示为自动配置IPV4 169.254的地址
  8. stringbuffer java API_java API中Object,String,Stringbuffer,StringBuilder的总结
  9. 宁波保哥后院_如何抛出终极后院电影之夜
  10. python 拼音输入法_隐马尔科夫模型python实现简单拼音输入法
  11. hdu 2037 今年暑假不AC 贪心)
  12. 《java程序员面试笔试宝典》学习笔记
  13. 神经网络量化--per-channel量化
  14. 【GAMES101 课程小结】:Lecture 13 Ray Tracing
  15. 解决word转PDF文件时图片位置改变和字体格式改变的问题
  16. 【C语言】强符号和弱符号
  17. 每日一招:什么样的股票才能越跌越买
  18. 单元覆盖测试排除某些类烧苗_智慧树人体生理学第一单元章节测试网课答案选修课慕课答案...
  19. 日本交通卡-SUICA卡
  20. 【MySQL】增删查改(进阶)

热门文章

  1. nginx https 访问http_Nginx之Http模块系列之访问控制模块
  2. 2.控制反转 spring_ioc
  3. linux 内核 ntfs,Linux大脑 内核 内核编译(NTFS)
  4. php和dart的区别,Dart相等和关系运算符
  5. 二十、预处理CSS的LESS
  6. AAAI 2022 | 可解释和鲁棒的联合文本分类及证据提取
  7. Industry AI Live | BERT在美团搜索业务中的应用
  8. 线下课程推荐 | 知识图谱理论与实战:构建行业知识图谱 (第四期)
  9. CVPR2019接收结果公布了,但CVPR 2018的那些论文都怎么样了?
  10. 开源代码“All in One”:6 份最新「Paper + Code」等你复现 | PaperDaily #12