python_day10(笔记及练习)

类和对象
1. 类:一个抽象的概念,即生活中的”类别”。
2. 对象:类的具体实例,即归属于某个类别的”个体”。
3. 类是创建对象的”模板”。
– 数据成员:名词类型的状态。
– 方法成员:动词类型的行为。
4. 类与类行为不同,对象与对象数据不同。
语法
定义类
1. 代码
class 类名:
“””文档说明”””
def init(self,参数列表):
self.实例变量 = 参数
方法成员

2. 	说明

– 类名所有单词首字母大写.
init 也叫构造函数,创建对象时被调用,也可以省略。
– self 变量绑定的是被创建的对象,名称可以随意。
创建对象(实例化)
变量 = 构造函数 (参数列表)
实例成员
实例变量
1. 语法
(1) 定义:对象.变量名
(2) 调用:对象.变量名

2. 说明
(1) 首次通过对象赋值为创建,再次赋值为修改.

w01 = Wife()
w01.name = “丽丽”
w01.name = “莉莉”
(2) 通常在构造函数(init)中创建。
w01 = Wife(“丽丽”,24)
print(w01.name)
(3) 每个对象存储一份,通过对象地址访问。

3. 作用:描述某个对象的数据。
4. __dict__:对象的属性,用于存储自身实例变量的字典。

实例方法
1. 语法
(1) 定义: def 方法名称(self, 参数列表):
方法体
(2) 调用: 对象地址.实例方法名(参数列表)
不建议通过类名访问实例方法
2. 说明
(1) 至少有一个形参,第一个参数绑定调用这个方法的对象,一般命名为"self"。
(2) 无论创建多少对象,方法只有一份,并且被所有对象共享。
3. 作用:表示对象行为。

"""
    实例成员
        实例变量:对象不同的数据
        实例方法:对象相同行为
        核心逻辑:
           对象.?
"""


# 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"] = "双双"

类成员
类变量
1. 语法
(1) 定义:在类中,方法外定义变量。
class 类名:
变量名 = 表达式
(2) 调用:类名.变量名
不建议通过对象访问类变量
2. 说明
(1) 存储在类中。
(2) 只有一份,被所有对象共享。
3. 作用:描述所有对象的共有数据。

"""
    类成员
        类变量:大家的数据
        类方法:大家的行为
        核心逻辑:
            类.?
"""



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) 定义:
@classmethod
def 方法名称(cls,参数列表):
方法体
(2) 调用:类名.方法名(参数列表)
不建议通过对象访问类方法
2. 说明
(1) 至少有一个形参,第一个形参用于绑定类,一般命名为’cls’
(2) 使用@classmethod修饰的目的是调用类方法时可以隐式传递类。
(3) 类方法中不能访问实例成员,实例方法中可以访问类成员。
3. 作用:操作类变量。
静态方法
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)

    @staticmethod
    def get_up():
        return Vector2(-1, 0)

    @staticmethod
    def get_left():
        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:创建向左的静态方法
# 测试:让某个位置沿着该方向移动
up = Vector2.get_up()
pos.x += up.x
pos.y += up.y
print(pos.x,pos.y)












三大特征
封装
数据角度讲
1. 定义:
将一些基本数据类型复合成一个自定义类型。
2. 优势:
将数据与对数据的操作相关联。
代码可读性更高(类是对象的模板)。
行为角度讲
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, 写入方法名)

"""
    封装
        目标:保障数据有效性
        原理
        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()) # 通过方法读取数据
"""
    封装
        目标:保障数据有效性
        property 核心逻辑:拦截
        1. 创建实例变量
        2. 提供读取与写入方法(数据验证)
        3. 创建类变量(与实例变量名称相同),存储property对象
"""


class Wife:

    def __init__(self, name="", age=0):
        self.name = name
        # self.set_age(age)
        self.age = age

    def set_age(self, value):
        if 22 <= value <= 32:
            self.__age = value
        else:
            raise Exception("我不要")

    def get_age(self):
        return self.__age

    # property(读取方法,写入方法)
    age = property(get_age, set_age)

w01 = Wife("双儿", 25)
print(w01.name)
# print(w01.get_age())
print(w01.age)

"""
    封装
        目标:保障数据有效性
        property 核心逻辑:拦截
        1. 创建实例变量
        2. 提供读取与写入方法(数据验证)
        3. 创建类变量(与实例变量名称相同),存储property对象
"""


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)
"""
    创建类:敌人类
        实例变量:姓名,血量,防御力,攻击力
        方法:受伤 - 血量减少
             打印自身信息 - 打印所有实例变量
    创建敌人列表(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_enemys = [
    Enemy("成昆", 0, 10, 90),
    Enemy("玄冥一老", 90, 8, 80),
    Enemy("玄冥二老", 95, 9, 95),
]


# 练习1
def find01():
    list_result = []
    for item in list_enemys:
        if item.hp > 0:
            list_result.append(item)
    return list_result


# 测试
# for item in find01():
#     item.print_self()

for item in find01():
    item.damage()


# 练习2
def find02():
    list_result = []
    for item in list_enemys:
        if item.atk > 50:
            list_result.append((item.name, item.atk))
    return list_result


# 测试    11:30
for item in find02():
    print(item)


# 练习3
def get_min_by_defense():
    min_value = list_enemys[0]
    for i in range(1, len(list_enemys)):
        if min_value.defense > list_enemys[i].defense:
            min_value = list_enemys[i]
    return min_value


# 测试
result = get_min_by_defense()
result.damage()


# 练习3  -- 定义函数,在敌人列表中删除血量大于50的所有敌人
def delete_all_by_hp():
    count = 0
    for i in range(len(list_enemys) - 1, -1, -1):
        if list_enemys[i].hp > 50:
            del list_enemys[i]
            count += 1
    return count


# print(delete_all_by_hp())

# 定义函数,根据攻击力进行降序排列
def sort():
    for r in range(len(list_enemys) - 1):
        for c in range(r + 1, len(list_enemys)):
            if list_enemys[r].atk < list_enemys[c].atk:
                list_enemys[r], list_enemys[c] = list_enemys[c], list_enemys[r]

sort()
for item in list_enemys:
    item.print_self()




"""
    创建对象计数器
    提示:统计__init__被调用的次数
    画出内存图
"""


class Wife:
    count = 0

    @classmethod
    def print_count(cls):
        print("总共娶了%d个老婆" % cls.count)

    def __init__(self, name=""):
        self.name = name
        Wife.count += 1


w01 = Wife("")
w02 = Wife("")
w03 = Wife("")
w04 = Wife("")
w05 = Wife("")
w06 = Wife("")
Wife.print_count()
"""
    属性练习
        创建敌人类
            数据:姓名,血量(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)


e01 = Enemy("灭霸", 500, 100)
print(e01.name)
print(e01.hp)
print(e01.atk)
e01.a = 9999999

你可能感兴趣的:(#,python基础)