昨天去答辩啦,所以就没有进行一个学习安排。今天是关于面向对象的封装。
属性:1.类外部 *** 作属性:对象.属性名= 属性值(可以是添加也可以是修改)
2.类内部 *** 作属性:self,方法的第一个形参,表示的是调用该方法的对象,使用对象去调用方法的时候,不需要手动的传递实参值,python解释器自动的将调用方法的对象传递给self形参
self.属性名 = 属性值
方法:1.普通方法:函数
2.魔法方法,形式:__***__,在满足某个条件的情况下会自动调用
如:__init__() __str__() __del__() __repr__()
# 类内部添加和获取对象属性
class Dog(object):
def play(self):
print('runrunrurn')
# 创建对象
dog = Dog()
dog.play()
# 给对象添加属性 对象.属性名 = 属性值
dog.name = '大黄' # 给对象添加name属性
dog.age = 2 # 给对象添加age属性
# 获取对象属性值 对象.属性名
print(dog.name)
print(dog.age)
# 修改属性值 如果存在就是修改,不存在就是添加
dog.age = 5 # 修改
print(dog.age)
# 每个对象会保存自己的属性值,不用的对象属性值之间没有关联
dog1 = Dog() # 新创建一个对象
dog1.name = '小白'
print(dog1.name)
# 类外部添加和获取对象属性
class Dog(object):
# self作为类中方法的第一个形参(self是一个形参名,可以写成其他名字,但一般不修改),
# 在通过调用方法的时候,不需要手动的传递实参值
# 是python解释器自动将调用该方法的对象传递给self,
# 所以self这个形参代表的是对象
def play(self):
print(f'dog{self.name} runurn...')
dog = Dog()
dog.name = '大黄'
print(f'dog:{id(dog)}')
dog.play()
print('**'*30)
dog1 = Dog()
dog1.name = '小白'
print(f'dog1:{id(dog1)}')
dog1.play()
# 魔法方法
# 在python的类中,__init__,并且在满足某个特定条件的情况下
# 会自动调用这类方法,称为魔法方法
# 学习方法:1.什么情况下会自动调用?2.魔法方法的作用?3.注意事项是什么?
# __init__ ()
# 调用时机:在创建对象之后,会立即调用
# 作用:1.用来给对象添加属性,给对象属性一个初始值(构造函数)
# 2.代码的业务需求,每创建一个对象都需要执行的代码可以写在init中
class Dog(object):
def __init__(self):
print('我是__init__,调用啦')
# 对象.属性名 = 属性值
self.name = '小狗'
# 创建对象
# Dog()
dog = Dog()
print(dog.name)
dog1 = Dog()
print(dog1.name)
# 书写带参数的init方法
class Dog(object):
def __init__(self,name):
print('我是__init__,调用啦')
# 对象.属性名 = 属性值
self.name = name
# 创建对象
# Dog()
dog = Dog('小白')
print(dog.name)
dog1 = Dog('小黄')
print(dog1.name)
# 注意点:如果该方法有除了self以外的形参,那么在创建对象的时候就需要给额外的形参传递实参值
# __str__
# 调用时机:1.print(对象),会自动调用该方法,打印输出的结果是该方法的返回值
# 2.str(对象) ,类型转换,将自定义对象转换为字符串的时候,会自动调用
# 应用:1.打印对象的时候,输出一些属性信息
# 2. 需要将对象转换为字符串类型的时候
# 注意点:方法必须返回一个字符串,只有self一个参数
class Dog(object):
def __init__(self,name,age):
#添加属性
self.name = name
self.age = age
def __str__(self):
print('我是__str__') # 为了验证调用了该方法
# 必须返回一个字符串
return f'小狗的名字是{self.name},年龄是{self.age}'
dog = Dog('大黄',18)
print(dog) # 没有定义__str__方法,默认print(对象)默认输出对象的引用地址<__main__.Dog object at 0x000001741F532D90>
str_dog = str(dog)
print(str_dog) # 没有定义__str__方法,类型转化,复制的也是引用地址<__main__.Dog object at 0x000001741F532D90>
# __del__ (析构函数)
# 调用时机:对象在内存中被销毁删除的时候会自动调用该方法
# 程序代码运行结束,在程序运行过程中,创建的所有对象和变量都会被删除销毁
# 使用‘del 变量’,将这哥对象的引用计数变为0,会自动调用该方法
# 引用计数:是指一块内存,有多少个变量在引用。1.当一个变量引用一块内存的时候,引用计数+1,删除一个变量或者不再引用-1,
# 当内存的引用计数变为0,这块内存就被删除,内存中的数据被销毁
# 应用场景:对象被删除销毁的时候可以写在该函数中,一般很少使用
class Dog(object):
def __init__(self,name,age):
#添加属性
self.name = name
self.age = age
def __str__(self):
print('我是__str__') # 为了验证调用了该方法
# 必须返回一个字符串
return f'小狗的名字是{self.name},年龄是{self.age}'
def __del__(self):
print('我是__del__')
# dog = Dog('大黄',12)
# dog1 = Dog('小白',13)
dog = Dog('笑话',3) # 笑话 引用计数为1
dog2 = dog # 笑话 引用计数2
print('first')
del dog # dog变量不能使用使用,笑话引用计数1
print('second')
del dog2 # dog2变量不能使用,笑话对象引用计数为0,会立即调用__del__
# 查看对象的引用计数
import sys
class Dog(object):
pass
dog = Dog()
print(sys.getrefcount(dog)) # 显示的时候会比实际多一个
dog1 = Dog()
print(sys.getrefcount(dog1))
# 补充:__repr__
my_list = ['hello','python','you'] # 列表中存储了三个字符串对象
print(my_list) # ['hello', 'python', 'you']
class Dog(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return f'{self.name},{self.age}'
def __repr__(self): # 这个方法和str方法非常类似,要返回一个字符串
return f'{self.name}' # [1, 3, 5]
my_list1 = [Dog(1,2),Dog(3,4),Dog(5,6)] # 将三个类对象添加到列表中
print(my_list1) # [<__main__.Dog object at 0x000002BB8AE0CFD0>, <__main__.Dog object at 0x000002BB8AE0CF10>, <__main__.Dog object at 0x000002BB8AE0CD60>]
案例:
1.烤地瓜
# 封装的小套路:
# 1.根据文字的描述信息,确认对象,对象有什么就是属性
# 2.根据文字的描述信息,对象能干什么,就是方法
# 3.根据文字的描述信息,确定方法怎么书写
# 类名:Potato
# 属性:状态status=生的
# 烧烤总时间 total_time = 0
# 方法:def cook(self,烧烤时间):
# 计算烧烤的总时间
# 修改地瓜的状态
# pass
# 输出信息 __str__()
# 定义属性 __init__()
class Potato(object):
def __init__(self):
self.status = '生的'
self.total_time = 0
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):
return f'地瓜的状态{self.status},总时间{self.total_time}'
# 创建对象,开始烤
potato = Potato()
print(potato)
potato.cook(4)
print(potato)
potato.cook(3)
print(potato)
加调料的版本:
# 烤地瓜调料版
# 属性:保存调料:name,使用列表保存 name_list = []
# 方法:添加调料add()
class Potato(object):
def __init__(self):
self.status = '生的'
self.total_time = 0
self.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 = str(self.name_list) 这里不能去掉中括号
# 怎么去掉中括号?
# 字符串.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)
potato.add('油')
potato.cook(4)
potato.add('糖')
print(potato)
potato.cook(3)
potato.add('盐')
print(potato)
2.搬家具
# 类名:Furniture
# 属性:类型 name,面积 area
# 方法:输出家具信息 __str__ 定义属性 __init__
# 类名:House
# 属性:地址 address 面积 h_area 家具列表 furniture.list
# 方法:添加家具 add_furniture 输出房子信息 __str__ 定义属性 __init__
class Furniture(object):
def __init__(self,name,area):
self.name = name
self.area = area
def __str__(self):
return f'家具的类型是:{self.name},占地面积{self.area}'
class House(object):
def __init__(self,address,area):
self.address = address
self.h_area = area
self.furniture_list = []
self.free_area = area # 房子的剩余面积
def add_furniture(self,obj_furniture): # 添加家具,参数代表家具类的对象
if self.free_area > obj_furniture.area:
self.furniture_list.append(obj_furniture)
# 修改剩余面积
self.free_area -= obj_furniture.area
print(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},还没有家具'
bed = Furniture('双人床',15)
print(bed)
house = House('意大利',100)
print(house)
house.add_furniture(bed)
print(house)
测试题:
# 1. 定义一个star类,创建一个对象
class Star(object):
pass
zhou = Star()
# 键盘循环输入5个对象和moving名字,分别调用打印
class Star(object):
def __init__(self,name,movie):
self.name = name
self.movie = movie
def playing(self):
print(f'{self.name}出演了{self.movie},好好看呀')
def __str__(self):
return f'{self.name}是我的偶像,我很喜欢他的电影:{self.movie}'
def __del__(self):
print(f'我不喜欢{self.name}了')
mov_list = [] # 将对象放入列表中
for i in range(3):
name = input('你喜欢的明星是:')
movie = input('你喜欢的电影是:')
s = Star(name,movie)
mov_list.append(s) # 将每个输入放入列表中
for i in mov_list: # 遍历列表
i.playing()
print(i)
# star = Star('周星驰','功夫')
# print(star)
# star1 = Star('周','怒')
# star1.playing()
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)