目录
面相对象基础语法
目标
01. dir 内置函数(知道)
02. 定义简单的类(只包含方法)
2.1 定义只包含方法的类
2.2 创建对象
2.3 第一个面向对象程序
03. 方法中的 self 参数
3.1 案例改造 —— 给对象增加属性
3.2 使用 self 在方法内部输出每一只猫的名字
04. 初始化方法
4.1 之前代码存在的问题 —— 在类的外部给对象增加属性
4.2 初始化方法
4.3 在初始化方法内部定义属性
4.4 改造初始化方法 —— 初始化的同时设置初始值
05. 内置方法和属性
5.1 __del__ 方法(知道)
5.2 __str__ 方法
面向对象封装案例
目标
01. 封装
02. 小明爱跑步
2.1 小明爱跑步扩展 —— 小美也爱跑步
03. 摆放家具
3.1 创建家具
3.2 创建房间
3.3 添加家具
3.4 小结
面向对象封装案例 II
目标
01. 士兵突击
1.1 开发枪类
1.2 开发士兵类
02. 身份运算符
is 与 == 区别:
私有属性和私有方法
01. 应用场景及定义方式
02. 伪私有属性和私有方法(科普)
dir
内置函数self
参数dir
内置函数(知道)Python
中 对象几乎是无所不在的,我们之前学习的 变量、数据、函数 都是对象在 Python
中可以使用以下两个方法验证:
.
,然后按下 TAB
键,iPython
会提示该对象能够调用的 方法列表dir
传入 标识符 / 数据,可以查看对象内的 所有属性及方法提示 __方法名__
格式的方法是 Python
提供的 内置方法 / 属性,稍后会给大家介绍一些常用的 内置方法 / 属性
序号 | 方法名 | 类型 | 作用 |
---|---|---|---|
01 | __new__ |
方法 | 创建对象时,会被 自动 调用 |
02 | __init__ |
方法 | 对象被初始化时,会被 自动 调用 |
03 | __del__ |
方法 | 对象被从内存中销毁前,会被 自动 调用 |
04 | __str__ |
方法 | 返回对象的描述信息,print 函数输出使用 |
提示 利用好 dir()
函数,在学习时很多内容就不需要死记硬背了
面向对象 是 更大 的 封装,在 一个类中 封装 多个方法,这样 通过这个类创建出来的对象,就可以直接调用这些方法了!
Python
中要定义一个只包含方法的类,语法格式如下:class 类名:
def 方法1(self, 参数列表):
pass
def 方法2(self, 参数列表):
pass
self
,大家暂时先记住,稍后介绍 self
注意:类名 的 命名规则 要符合 大驼峰命名法
对象变量 = 类名()
需求
分析
Cat
eat
和 drink
class Cat:
"""这是一个猫类"""
def eat(self):
print("小猫爱吃鱼")
def drink(self):
print("小猫在喝水")
tom = Cat()
tom.drink()
tom.eat()
引用概念的强调
在面向对象开发中,引用的概念是同样适用的!
Python
中使用类 创建对象之后,tom
变量中 仍然记录的是 对象在内存中的地址tom
变量 引用 了 新建的猫对象print
输出 对象变量,默认情况下,是能够输出这个变量 引用的对象 是 由哪一个类创建的对象,以及 在内存中的地址(十六进制表示)提示:在计算机中,通常使用 十六进制 表示 内存地址
- 十进制 和 十六进制 都是用来表达数字的,只是表示的方式不一样
- 十进制 和 十六进制 的数字之间可以来回转换
%d
可以以 10 进制 输出数字%x
可以以 16 进制 输出数字案例进阶 —— 使用 Cat 类再创建一个对象
lazy_cat = Cat()
lazy_cat.eat()
lazy_cat.drink()
提问:
tom
和lazy_cat
是同一个对象吗?
self
参数Python
中,要 给对象设置属性,非常的容易,但是不推荐使用
.
设置一个属性即可注意:这种方式虽然简单,但是不推荐使用!
tom.name = "Tom"
...
lazy_cat.name = "大懒猫"
self
在方法内部输出每一只猫的名字由 哪一个对象 调用的方法,方法内的
self
就是 哪一个对象的引用
self
就表示 当前调用方法的对象自己self
参数self.
访问对象的属性self.
调用其他的对象方法class Cat:
def eat(self):
print("%s 爱吃鱼" % self.name)
tom = Cat()
tom.name = "Tom"
tom.eat()
lazy_cat = Cat()
lazy_cat.name = "大懒猫"
lazy_cat.eat()
变量名.
访问对象的 属性和方法self.
访问对象的 属性和方法tom = Cat()
tom.drink()
tom.eat()
tom.name = "Tom"
print(tom)
AttributeError: 'Cat' object has no attribute 'name'
属性错误:'Cat' 对象没有 'name' 属性
提示
类名()
创建对象时,会 自动 执行以下操作:
init
)__init__
方法,__init__
是对象的内置方法
__init__
方法是 专门 用来定义一个类 具有哪些属性的方法!
在 Cat
中增加 __init__
方法,验证该方法在创建对象时会被自动调用
class Cat:
"""这是一个猫类"""
def __init__(self):
print("初始化方法")
__init__
方法内部使用 self.属性名 = 属性的初始值
就可以 定义属性Cat
类创建的对象,都会拥有该属性class Cat:
def __init__(self):
print("这是一个初始化方法")
# 定义用 Cat 类创建的猫对象都有一个 name 的属性
self.name = "Tom"
def eat(self):
print("%s 爱吃鱼" % self.name)
# 使用类名()创建对象的时候,会自动调用初始化方法 __init__
tom = Cat()
tom.eat()
__init__
方法进行 改造
__init__
方法的参数self.属性 = 形参
接收外部传递的参数类名(属性1, 属性2...)
调用class Cat:
def __init__(self, name):
print("初始化方法 %s" % name)
self.name = name
...
tom = Cat("Tom")
...
lazy_cat = Cat("大懒猫")
...
序号 | 方法名 | 类型 | 作用 |
---|---|---|---|
01 | __del__ |
方法 | 对象被从内存中销毁前,会被 自动 调用 |
02 | __str__ |
方法 | 返回对象的描述信息,print 函数输出使用 |
__del__
方法(知道)在 Python
中
类名()
创建对象时,为对象 分配完空间后,自动 调用 __init__
方法__del__
方法应用场景
__init__
改造初始化方法,可以让创建对象更加灵活__del__
如果希望在对象被销毁前,再做一些事情,可以考虑一下 __del__
方法生命周期
类名()
创建,生命周期开始__del__
方法一旦被调用,生命周期结束class Cat:
def __init__(self, new_name):
self.name = new_name
print("%s 来了" % self.name)
def __del__(self):
print("%s 去了" % self.name)
# tom 是一个全局变量
tom = Cat("Tom")
print(tom.name)
# del 关键字可以删除一个对象
del tom
print("-" * 50)
__str__
方法Python
中,使用 print
输出 对象变量,默认情况下,会输出这个变量 引用的对象 是 由哪一个类创建的对象,以及 在内存中的地址(十六进制表示)print
输出 对象变量 时,能够打印 自定义的内容,就可以利用 __str__
这个内置方法了注意:
__str__
方法必须返回一个字符串
class Cat:
def __init__(self, new_name):
self.name = new_name
print("%s 来了" % self.name)
def __del__(self):
print("%s 去了" % self.name)
def __str__(self):
return "我是小猫:%s" % self.name
tom = Cat("Tom")
print(tom)
需求
75.0
公斤0.5
公斤1
公斤提示:在 对象的方法内部,是可以 直接访问对象的属性 的!
class Person:
"""人类"""
def __init__(self, name, weight):
self.name = name
self.weight = weight
def __str__(self):
return "我的名字叫 %s 体重 %.2f 公斤" % (self.name, self.weight)
def run(self):
"""跑步"""
print("%s 爱跑步,跑步锻炼身体" % self.name)
self.weight -= 0.5
def eat(self):
"""吃东西"""
print("%s 是吃货,吃完这顿再减肥" % self.name)
self.weight += 1
xiaoming = Person("小明", 75)
xiaoming.run()
xiaoming.eat()
xiaoming.eat()
print(xiaoming)
需求
75.0
公斤45.0
公斤0.5
公斤1
公斤提示
需求
4
平米2
平米1.5
平米剩余面积
add_item
方法,向房间 添加家具 时,让 剩余面积 -= 家具面积思考:应该先开发哪一个类?
答案 —— 家具类
class HouseItem:
def __init__(self, name, area):
"""
:param name: 家具名称
:param area: 占地面积
"""
self.name = name
self.area = area
def __str__(self):
return "[%s] 占地面积 %.2f" % (self.name, self.area)
# 1. 创建家具
bed = HouseItem("席梦思", 4)
chest = HouseItem("衣柜", 2)
table = HouseItem("餐桌", 1.5)
print(bed)
print(chest)
print(table)
小结
__init__
和 __str__
两个内置方法class House:
def __init__(self, house_type, area):
"""
:param house_type: 户型
:param area: 总面积
"""
self.house_type = house_type
self.area = area
# 剩余面积默认和总面积一致
self.free_area = area
# 默认没有任何的家具
self.item_list = []
def __str__(self):
# Python 能够自动的将一对括号内部的代码连接在一起
return ("户型:%s\n总面积:%.2f[剩余:%.2f]\n家具:%s"
% (self.house_type, self.area,
self.free_area, self.item_list))
def add_item(self, item):
print("要添加 %s" % item)
...
# 2. 创建房子对象
my_home = House("两室一厅", 60)
my_home.add_item(bed)
my_home.add_item(chest)
my_home.add_item(table)
print(my_home)
小结
__init__
和 __str__
两个内置方法add_item
方法 准备添加家具add_item
方法,将 三件家具 以实参传递到 add_item
内部需求
def add_item(self, item):
print("要添加 %s" % item)
# 1. 判断家具面积是否大于剩余面积
if item.area > self.free_area:
print("%s 的面积太大,不能添加到房子中" % item.name)
return
# 2. 将家具的名称追加到名称列表中
self.item_list.append(item.name)
# 3. 计算剩余面积
self.free_area -= item.area
add_item
方法 将家具添加到房子中封装
一个对象的 属性 可以是 另外一个类创建的对象
需求
shoot
方法需求
print
提示射击,并且输出子弹数量class Gun:
def __init__(self, model):
# 枪的型号
self.model = model
# 子弹数量
self.bullet_count = 0
def add_bullet(self, count):
self.bullet_count += count
def shoot(self):
# 判断是否还有子弹
if self.bullet_count <= 0:
print("没有子弹了...")
return
# 发射一颗子弹
self.bullet_count -= 1
print("%s 发射子弹[%d]..." % (self.model, self.bullet_count))
# 创建枪对象
ak47 = Gun("ak47")
ak47.add_bullet(50)
ak47.shoot()
假设:每一个新兵 都 没有枪
定义没有初始值的属性
在定义属性时,如果 不知道设置什么初始值,可以设置为 None
None
关键字 表示 什么都没有None
赋值给任何一个变量fire
方法需求
class Soldier:
def __init__(self, name):
# 姓名
self.name = name
# 枪,士兵初始没有枪 None 关键字表示什么都没有
self.gun = None
def fire(self):
# 1. 判断士兵是否有枪
if self.gun is None:
print("[%s] 还没有枪..." % self.name)
return
# 2. 高喊口号
print("冲啊...[%s]" % self.name)
# 3. 让枪装填子弹
self.gun.add_bullet(50)
# 4. 让枪发射子弹
self.gun.shoot()
小结
__init__
内置方法None
身份运算符用于 比较 两个对象的 内存地址 是否一致 —— 是否是对同一个对象的引用
Python
中针对 None
比较时,建议使用 is
判断运算符 | 描述 | 实例 |
---|---|---|
is | is 是判断两个标识符是不是引用同一个对象 | x is y,类似 id(x) == id(y) |
is not | is not 是判断两个标识符是不是引用不同对象 | x is not y,类似 id(a) != id(b) |
is
用于判断 两个变量 引用对象是否为同一个 ==
用于判断 引用变量的值 是否相等
>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> b is a
False
>>> b == a
True
应用场景
定义方式
class Women:
def __init__(self, name):
self.name = name
# 不要问女生的年龄
self.__age = 18
def __secret(self):
print("我的年龄是 %d" % self.__age)
xiaofang = Women("小芳")
# 私有属性,外部不能直接访问
# print(xiaofang.__age)
# 私有方法,外部不能直接调用
# xiaofang.__secret()
提示:在日常开发中,不要使用这种方式,访问对象的 私有属性 或 私有方法
Python
中,并没有 真正意义 的 私有
_类名
=> _类名__名称
# 私有属性,外部不能直接访问到
print(xiaofang._Women__age)
# 私有方法,外部不能直接调用
xiaofang._Women__secret()
感谢各位大佬的观看,小编这边准备了一个既能学习交流的也能接单的qq群聊 :222020937【代码也准备好了】 欢迎加入《广告勿加,不然你做啥啥不赚钱》最后祝大家技术能力能越来越好收入越来越多