实例成员
实例变量:对象不同的数据
实例方法:对象相同行为
核心逻辑:
对象.?
1. 标准写法
class Wife:
def init(self, name):
# 创建实例变量:对象.变量名 = 数据
self.name = name
def print_self(self):
print(“我叫:”, self.name)
def play(self):
print(“在玩耍”)
# 对象.方法名()
self.print_self()
w01 = Wife(“双儿”)
w02 = Wife(“阿珂”)
#读取实例变量:? = 对象.变量名
print(w01.name)
#内置实例变量
#-- 获取当前对象所有实例变量
print(w01.dict)
w01.play()
w02.play()
#2. 不建议(实例变量应该由类的定义者决定)
# class Wife:
# pass
# w01 = Wife()
# # 创建实例变量:对象.变量名 = 数据
# w01.name = "双儿"
# # 读取实例变量:? = 对象.变量名
# print(w01.name)
# 3. 不建议(实例变量应该直接在init中定义)
# class Wife:
# def init(self):
# pass
# def func01(self,name):
# # 创建实例变量:对象.变量名 = 数据
# self.name = name
#
# w01 = Wife()
# w01.func01(“双儿”)
# # 读取实例变量:? = 对象.变量名
# print(w01.name)
dict01 = {}
dict01[“name”] = “双儿”
dict01[“name”] = “双双”
类成员
类变量:大家的数据
类方法:大家的行为
核心逻辑:
类.?
class ICBC:
总行的钱
total_money = 1000000
@classmethod
def print_total_money(cls):
print(“总行的钱:”, cls.total_money)
def init(self, name="", money=0):
# 实例变量
self.name = name
# 支行的钱
self.money = money
# 从总行扣除当前支行需要的钱
ICBC.total_money -= money
i01 = ICBC(“天坛支行”, 100000)
i02 = ICBC(“陶然亭支行”, 200000)
# print(“总行的钱:”,ICBC.total_money)
ICBC.print_total_money() # print_total_money(ICBC)
静态方法
1. 语法
(1) 定义:
@staticmethod
def 方法名称(参数列表):
方法体
(2) 调用:类名.方法名(参数列表)
不建议通过对象访问静态方法
2. 说明
(1) 使用@ staticmethod修饰的目的是该方法不需要隐式传参数。
(2) 静态方法不能访问实例成员和类成员
3. 可以独立存在的工具函数
class Vector2:
“”"
二维向量
“”"
def init(self, x, y):
self.x = x
self.y = y
@staticmethod
def get_right():
“”"
静态方法
“”"
return Vector2(0, 1)
list01 = [
[“00”, “01”, “02”, “03”],
[“10”, “11”, “12”, “13”],
[“20”, “21”, “22”, “23”],
[“30”, “31”, “32”, “33”],
]
# 位置
pos = Vector2(1, 2)
# 方向
# right = Vector2(0, 1)
right = Vector2.get_right()
# 需求:沿着某个方向移动
pos.x += right.x
pos.y += right.y
print(pos.x,pos.y)
封装
目标:保障数据有效性
1. 私有化数据(不隐藏在类外就可以随意操作,无法进行限制)
2. 提供读取与写入方法(数据验证)
class Wife:
def init(self, name="", age=0):
self.name = name
# self.__age = age
self.set_age(age)
def set_age(self, value):
if 22 <= value <= 32:
self.__age = value
else:
raise Exception(“我不要”)
def get_age(self):
return self.__age
w01 = Wife(“双儿”, 25)
print(w01.name)
# print(w01.__age) # 不能访问私有变量
print(w01.get_age()) # 通过方法读取数据
行为角度讲
1. 定义:
向类外提供必要的功能,隐藏实现的细节。
2. 优势:
简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。
3. 私有成员:
(1) 作用:无需向类外提供的成员,可以通过私有化进行屏蔽。
(2) 做法:命名使用双下划线开头。
(3) 本质:障眼法,实际也可以访问。
私有成员的名称被修改为:_类名__成员名,可以通过_dict_属性或dir函数查看。
4. 属性@property:
公开的实例变量,缺少逻辑验证。私有的实例变量与两个公开的方法相结合,又使调用者的操作略显复杂。而属性可以将两个方法的使用方式像操作变量一样方便。
(1) 定义:
@property
def 属性名(self):
return self.__属性名
@属性名.setter
def 属性名(self, value):
self.__属性名= value
(2) 调用:
对象.属性名 = 数据
变量 = 对象.属性名
(3) 说明:
通常两个公开的属性,保护一个私有的变量。
@property 负责读取,@属性名.setter 负责写入
只写:属性名= property(None, 写入方法名)
class Wife:
def init(self, name="", age=0):
self.name = name
self.age = age
@property # age = property(读取方法, None)
def age(self):
return self.__age
@age.setter #
def age(self, value):
if 22 <= value <= 32:
self.__age = value
else:
raise Exception(“我不要”)
w01 = Wife(“双儿”, 25)
print(w01.name)
print(w01.get_age())
print(w01.age)
练习1:
"""
创建类:敌人类
实例变量:姓名,血量,防御力,攻击力
方法:受伤 血量减少
打印自身信息 -- 打印所有实例变量
创建敌人列表(3)
-- 定义函数,找出所有活的敌人
-- 定义函数,找出攻击力大于50的敌人名称与攻击力
-- 定义函数,在敌人列表中找出防御力最小的对人
-- 定义函数,在敌人列表中删除血量大于50的所有敌人
-- 定义函数,根据攻击力降序排列
"""
class Enemy():
def __init__(self, name, hp=0, defense=0, atk=0):
self.name = name
self.hp = hp
self.defense = defense
self.atk = atk
def damage(self):
self.hp -= 10
print(self.name, "被攻击,血量减少10")
def print_self(self):
print("我是%s血量%d防御力%d攻击力%d" % (self.name, self.hp, self.defense, self.atk))
list_enemy = [
Enemy("关羽", 90, 100, 101),
Enemy("刘备", 30, 101, 30),
Enemy("张飞", 89, 90, 100),
Enemy("小兵", 0, 10, 5),
]
# -- 定义函数,找出所有活的敌人
def find01():
list_result = []
for item in list_enemy:
if item.hp > 0:
list_result.append(item)
return list_result
for item in find01():
item.damage()
for item in find01():
item.print_self()
# -- 定义函数,找出攻击力大于50的敌人名称与攻击力
def find02():
list_result = []
for item in list_enemy:
if item.atk > 50:
list_result.append((item.name, item.atk))
return list_result
for item in find02():
print(item)
# -- 定义函数,在敌人列表中找出防御力最小的对人
def find03():
min_name = list_enemy[0]
for i in range(1, len(list_enemy)):
if min_name.defense > list_enemy[i].defense:
min_name = list_enemy[i]
return min_name
result = find03()
result.damage()
# -- 定义函数,在敌人列表中删除血量大于50的所有敌人
def find04():
count = 0
for i in range(len(list_enemy) - 1, -1, -1):
if list_enemy[i].hp > 50:
del list_enemy[i]
count += 1
return count
print(find04())
# -- 定义函数,根据攻击力降序排列
def find05():
for r in range(len(list_enemy)):
for c in range(r + 1, len(list_enemy)):
if list_enemy[r].atk < list_enemy[c].atk:
list_enemy[r], list_enemy[c] = list_enemy[c], list_enemy[r]
for item in list_enemy:
item.print_self()
练习2:
"""
创建对象计数器
提示:统计_init_被调用的次数
"""
class Wife:
count = 0
@classmethod
def print_count(cls):
print("总共取了%d个老婆" % cls.count)
def __init__(self, name, age=0):
self.name = name
self.age = age
Wife.count += 1
w01 = Wife("李")
w02 = Wife("栗")
w03 = Wife("郭")
w04 = Wife("曹")
w05 = Wife("赵")
w06 = Wife("孙")
Wife.print_count()
练习3:
"""
创建向下的的静态方法
创建向左的静态方法
"""
class move:
def __init__(self, x, y):
self.x = x
self.y = y
@staticmethod
def up():
return move(-1, 0)
@staticmethod
def left():
return move(1, -1)
list01 = [
["00", "01", "02", "03"],
["10", "11", "12", "13"],
["20", "21", "22", "23"],
["30", "31", "32", "33"],
]
pos = move(1, 2)
right = move.up()
pos.x += right.x
pos.y += right.y
print(pos.x, pos.y)
right = move.left()
pos.x += right.x
pos.y += right.y
print(pos.x, pos.y)
练习4:
"""
属性练习
创建敌人类
数据:姓名,血量(0--500),攻击力(10--100)
创建敌人对象,体会拦截的核心逻辑
"""
class Enemy():
def __init__(self, name="", hp=0, atk=0):
self.name = name
self.hp = hp
self.atk = atk
def set_hp(self, value):
if 0 <= value <= 500:
self.__hp = value
else:
raise Exception("血量超过范围")
def get_hp(self):
return self.__hp
hp = property(get_hp, set_hp)
def set_atk(self, data):
if 10 <= data <= 100:
self.__atk = data
else:
raise Exception("攻击力超过范围")
def get_atk(self):
return self.__atk
atk = property(get_atk, set_atk)
enemy01 = Enemy("关羽", 500, 50)
print(enemy01.name)
print(enemy01.hp)
print(enemy01.atk)