Welcome to kimi's blog

面向对象之类与对象

面向对象

引入

人狗大战

"""推导步骤1:代码定义出人和狗"""
# 编写代码简单的实现人打狗 狗咬人的小游戏(剧情需要)
person1 = {
    'name': 'kevin',
    'age': 18,
    'gender': 'male',
    'p_type': '猛男',
    'attack_val': 8000,
    'life_val': 99999
}
person2 = {
    'name': 'kiki',
    'age': 24,
    'gender': 'female',
    'p_type': '淑女',
    'attack_val': 1200,
    'life_val': 1000
}

dog1 = {
    'name': '小黑',
    'd_type': '泰迪',
    'attack_val': 1000,
    'life_val': 800
}
dog2 = {
    'name': '小白',
    'd_type': '恶霸',
    'attack_val': 200,
    'life_val': 8000
}

"""推导步骤2:将产生人和狗的字典封装成函数并封装人和狗的攻击函数"""
# ps:如果想要定义出多个人和多条狗 上述的字典需要反复编写很多次

def create_person(name, age, gender, p_type, attack_val, life_val):
    person_dict = {
        'name': name,
        'age': age,
        'gender': gender,
        'p_type': p_type,
        'attack_val': attack_val,
        'life_val': life_val
    }
    return person_dict
def create_dog(name, d_type, attack_val, life_val):
    dog_dict = {
        'name': name,
        'd_type': d_type,
        'attack_val': attack_val,
        'life_val': life_val
    }
    return dog_dict

p1 = create_person('kevin',18,'male','猛男',8000,99999)
p2 = create_person('kiki',24,'female','淑女',1200,1000)
d1 = create_dog('小黑', '泰迪', 1000, 800)
d2 = create_dog('小白', '恶霸', 200, 8000)
print(p1,p2)
print(d1,d2)

结果展示:
print(p1,p2)  #{'name': 'kevin', 'age': 18, 'gender': 'male', 'p_type': '猛男', 'attack_val': 8000, 'life_val': 99999} {'name': 'kiki', 'age': 24, 'gender': 'female', 'p_type': '淑女', 'attack_val': 1200, 'life_val': 1000}
print(d1,d2)  #{'name': '小黑', 'd_type': '泰迪', 'attack_val': 1000, 'life_val': 800} {'name': '小白', 'd_type': '恶霸', 'attack_val': 200, 'life_val': 8000}

# 定义出人打狗的动作 狗咬人的动作
def person_attack(person_dict, dog_dict):
    print(f"人:{person_dict.get('name')}准备揍狗:{dog_dict.get('name')}")
    dog_dict['life_val'] -= person_dict.get('attack_val')
    print(f"人揍了狗一拳 狗掉血:{person_dict.get('attack_val')} 狗剩余血量:{dog_dict.get('life_val')}")
def dog_attack(dog_dict, person_dict):
    print(f"狗:{dog_dict.get('name')}准备咬人:{person_dict.get('name')}")
    person_dict['life_val'] -= dog_dict.get('attack_val')
    print(f"狗咬了人一口 人掉血:{dog_dict.get('attack_val')} 人剩余血量:{person_dict.get('life_val')}")
person_attack(p1, d1)
dog_attack(d2, p2)

结果打印:
    人:kevin准备揍狗:小黑
    人揍了狗一拳 狗掉血:8000 狗剩余血量:-7200
    狗:小白准备咬人:kiki
    狗咬了人一口 人掉血:200 人剩余血量:800
"""推导步骤3:人和狗的攻击混乱"""
person_attack(d1, p1)
dog_attack(p1, d2)

结果打印:
    人:小黑准备揍狗:kevin
    人揍了狗一拳 狗掉血:1000 狗剩余血量:98999
    狗:kevin准备咬人:小白
    狗咬了人一口 人掉血:8000 人剩余血量:0

>>>>>:如果想要人调属于人类的数据和方法,小狗调用属于犬类的数据和方法,那么就引入了面向对象思维
"""推导步骤4:如何实现只有人只能调用的人的攻击动作  狗只能调用狗的攻击动作>>>:数据与功能的绑定"""

def get_person(name, age, gender, p_type, attack_val, life_val):
    # 产生人的函数(功能)
    def person_attack(person_dict, dog_dict):
        print(f"人:{person_dict.get('name')}准备揍狗:{dog_dict.get('name')}")
        dog_dict['life_val'] -= person_dict.get('attack_val')
        print(f"人揍了狗一拳 狗掉血:{person_dict.get('attack_val')} 狗剩余血量:{dog_dict.get('life_val')}")
    # 表示人的信息(数据)
    person_dict = {
        'name': name,
        'age': age,
        'gender': gender,
        'p_type': p_type,
        'attack_val': attack_val,
        'life_val': life_val,
        'person_attack': person_attack
    }
    return person_dict


def get_dog(name, d_type, attack_val, life_val):
    def dog_attack(dog_dict, person_dict):
        print(f"狗:{dog_dict.get('name')}准备咬人:{person_dict.get('name')}")
        person_dict['life_val'] -= dog_dict.get('attack_val')
        print(f"狗咬了人一口 人掉血:{dog_dict.get('attack_val')} 人剩余血量:{person_dict.get('life_val')}")
    dog_dict = {
        'name': name,
        'd_type': d_type,
        'attack_val': attack_val,
        'life_val': life_val,
        'dog_attack': dog_attack
    }
    return dog_dict

person1 = get_person('kevin',18,'male','猛男',8000,99999)
dog1 = get_dog('小黑', '泰迪', 1000, 800)
print(person1)
print(dog1)

结果打印:
{'name': 'kevin', 'age': 18, 'gender': 'male', 'p_type': '猛男', 'attack_val': 8000, 'life_val': 99999, 'person_attack': <function get_person.<locals>.person_attack at 0x000002434A598820>}
{'name': '小黑', 'd_type': '泰迪', 'attack_val': 1000, 'life_val': 800, 'dog_attack': <function get_dog.<locals>.dog_attack at 0x000002434A5988B0>}

面向对象核心思想:数据与功能的绑定

面向对象编程思想

编程思想

1.面向过程编程

过程即流程 面向过程就是按照固定的流程解决问题
eg:截止ATM为止,使用的几乎都是面向过程编辑
	注册功能、登录功能、转账功能
	需要列举出每一步的流程,并随着步骤的深入,问题的解决越来越简单
	提出问题>>>>:制定出该问题的解决方案

2.面向对象编程

对象即容器   数据与功能(方法)的结合体 (在python中一切皆对象)
	eg:游戏人物  亚索
面向对象编程有点类似与造物主的感觉   我们只需要造出一个个对象
至于该对象将来如何发展跟程序员无关,也无法控制
	eg:王者荣耀里面的一个个英雄,比如小乔只能调用自己的三个技能,不能调用貂蝉的三技能,但是小乔的战绩只能靠玩小乔的操作者决定的,程序员无法控制的,全靠使用者操作技术决定

3.两种思路的对比

上述两种编程思想没有优劣之分,需要结合实际需求而定。

    如果需要注册、登录、人脸识别肯定面向过程更合适
    如果需求是游戏人物肯定是面向对象更合适

实际编程两种思想是彼此交融的,只不过占比不同

面向对象之类与对象

对象与类的概念

对象:数据与功能(方法)的结合体         对象才是核心
类: 多个对象相同数据和功能的结合体      类主要就是为了节省代码

程序中如果想产生对象,必须先有类,但生活中,一般先有对象再有类

    eg:
    一个人          对象
    一群人          人类(所有人相同的特征)

    一条狗          对象
    一群狗          犬类(所有狗相同的特征)

类与对象的创建

面对对象并不是一门新的技术,针对面向对象设计了新的语法格式
python中一定先有类,才能借助于类产生对象

1.语法格式

class 类名:
	"""代码注释"""
	对象公共的数据
	对象功公共的功能(方法)
1.class 是定义类的关键字
2.类名的命名与变量名几乎一致,需要注意的是>>>首字母推荐大写用于区分
3.数据:变量名与数据值的绑定,功能(方法)其实就是函数

2.类的定义与调用

类在定义阶段就会执行类体代码,但是属于类的局部名称空间,外界无法直接调用

类的定义

# 需求:人民大学选课系统
class Student:
    # 对象公共的数据
    school_name = '人民大学'

    # 对象公共的功能
    def choice_course(self):
        print('学生选课功能')

# 1.查看名称空间
print(Student.__dict__)  # {'__module__': '__main__','school_name': '人民大学', 'choice_course': <function Student.choice_course at 0x000002D3E14F8790>,.......}
print(Student.__dict__.get('school_name'))  # 人民大学
Student.__dict__.get('choice_course')  # 无

""" 2.在面向对象中,类和对象访问数据或者功能,可以采用句点符"""
print(Student.school_name)  # 人民大学
print(Student.choice_course)  # <function Student.choice_course at 0x000002AA30FF8160>

类的调用>>>产生对象

""" 类名加括号就会产生对象,并且每执行一次都会产生了一个全新的对象"""
# 1.类名加括号>>>对象
obj1 = Student()  # <__main__.Student object at 0x0000028783BF3B50>
obj2 = Student()  # <__main__.Student object at 0x0000028783BF3AF0>
obj3 = Student()  # <__main__.Student object at 0x0000028783C00100>
print(obj1,obj2,obj3)  # 变量名obj1接收类名加括号之后的返回值(结果)

# 2.通过对象点__dict__ 得到的是空的字典 ,这个字典并不是真是的字典
print(obj1.__dict__)  # {} 目前对象是空的
print(obj2.__dict__)  # {}
print(obj3.__dict__)  # {}

# 3.通过对象点类内的变量名  >>>:变量名绑定的数据值
print(obj1.school_name)  # 人民大学
print(obj2.school_name)  # 人民大学
print(obj3.school_name)  # 人民大学

# 4.类名修改类体代码内中的变量名绑定的数据值school_name
Student.school_name = '江南大学'
print(obj1.school_name)  # 江南大学
print(obj2.school_name)  # 江南大学
print(obj3.school_name)  # 江南大学

>>>>数据和功能  也称属性
>>>>数据       也称属性名
>>>>功能       也称方法

image
注意:类内的变量名,对象和类都可以通过点的方式使用

对象独有的数据

定义类

class Student:
    # 对象公共的数据
    school_name = '人民大学'

    # 对象公共的功能
    def choice_course(self):
        print('学生选课功能')

# 类名加括号>>>产生对象
obj1 = Student()
obj2 = Student()

推导流程1:每个对象手动添加独有的数据

# 为对象obj1添加独有的数据
print(obj1.__dict__)  # {}
obj1.__dict__['name'] = 'kimi'
obj1.__dict__['age'] = 18
obj1.__dict__['hobby'] = 'read'
print(obj1.__dict__)  # {'name': 'kimi', 'age': 18, 'hobby': 'read'}
# 输出结果
print(obj1.name)  # kimi
print(obj1.age)  # 18
print(obj1.hobby) # read

# 为对象obj2添加独有的数据
print(obj2.__dict__)  # {}
obj1.__dict__['name'] = 'rose'
obj1.__dict__['age'] = 22
obj1.__dict__['hobby'] = 'song'
print(obj1.__dict__)  # {'name': 'rose', 'age': 22, 'hobby': 'song'}
# 输出结果
print(obj1.name)  # rose
print(obj1.age)  # 22
print(obj1.hobby) # song

推导流程2:将添加对象独有数据的代码封装成函数

#1. 定义函数
def init(obj,name,age,hobby):
    obj.__dict__['name'] = name
    obj.__dict__['age'] = age
    obj.__dict__['hobby'] = hobby

#2. 产生对象
stu1 = Student()
stu2 = Student()

# 3.添加数据传给函数
init(stu1,'kimi',18,'read')
init(stu2,'rose',22,'sing')

# 打印结果
print(stu1.__dict__)  # {'name': 'kimi', 'age': 18, 'hobby': 'read'}
print(stu2.__dict__)  # {'name': 'rose', 'age': 22, 'hobby': 'sing'}

推导流程3:给学生对象添加独有数据的函数只有学生对象有资格调用

# 定义类
class Student:
    # 对象公共的数据
    school_name = '人民大学'

    # 专门给学生添加独有数据的功能
    def init(obj,name,age,hobby):
        obj.__dict__['name'] = name
        obj.__dict__['age'] = age
        obj.__dict__['hobby'] = hobby

    # 对象公共的功能
    def choice_course(self):
        print('学生选课功能')


# 类名加括号>>>产生对象
stu1 = Student()
stu2 = Student()

# 给类中的函数传数据
Student.init(stu1,'kimi',18,'read')
Student.init(stu1,'rose',22,'sing')
print(stu1.__dict__)  # {'name': 'kimi', 'age': 18, 'hobby': 'read'}
print(stu2.__dict__)  # {'name': 'rose', 'age': 22, 'hobby': 'sing'}

推导步骤4:init方法变形

# 定义类
class Student:
    # 对象公共的数据
    school_name = '人民大学'

    # 专门给学生添加独有数据的功能  类产生对象的过程中自动触发
    def __init__(obj, name, age, hobby):
        obj.__dict__['name'] = name
        obj.__dict__['age'] = age
        obj.__dict__['hobby'] = hobby

    # 对象公共的功能
    def choice_course(self):
        print('学生选课功能')

stu1 = Student('kimi', 18, 'read')
stu2 = Student('rose', 22, 'sing')
print(stu1.__dict__)  # {'name': 'kimi', 'age': 18, 'hobby': 'read'}
print(stu1.name)  # kimi
print(stu1.school_name)  # 人民大学

推导步骤5:变量名修改

class Student:
    # 对象公共的数据
    school_name = '人民大学'

    # 专门给学生添加独有数据的功能  类产生对象的过程中自动触发
    def __init__(self, name, age, hobby):
        self.name= name  # self.__dict__['name'] = name
        self.age = age   # self.__dict__['age'] = age
        self.hobby= hobby  # self.__dict__['hobby'] = hobby

    # 对象公共的功能
    def choice_course(self):
        print('学生选课功能')


stu1 = Student('kimi', 18, 'read')
print(stu1.name)  # kimi
print(stu1.school_name)  # 人民大学

对象独有的功能

class Student:
    # 对象公共的数据
    school_name = '人民大学'

    # 专门给学生添加独有数据的功能  类产生对象的过程中自动触发
    def __init__(self, name, age, hobby):
        self.name= name  # self.__dict__['name'] = name
        self.age = age
        self.hobby= hobby

    # 对象公共的功能
    def choice_course(self):
        print(f'学生{self.name}正在选课')


stu1 = Student('kimi', 18, 'read')

# 1.直接在全局定义功能,该函数就不是学生对象独有的了
def eat():
    print('吃东西')
stu1.eat = eat
# print(stu1.__dict__)  # {'name': 'kimi', 'age': 18, 'hobby': 'read', 'eat': <function eat at 0x0000021F41DF61F0>}
# stu1.eat()  # 吃东西

# 2.直接将函数放在类中,但是类中的函数又是对象公共的
'''定义在类中的功能 默认就是绑定给对象使用的 谁来调谁就是主人公'''
# Student.choice_course(123)  # 类调用需要自己传参数
# stu1.choice_course()  # choice_course(stu1) 对象调用会自动将对象当做第一个参数传入

stu1.choice_course()  # 学生kimi正在选课
stu2.choice_course()


# 对象修改数据值
stu1.name = 'swift'   # 当点的名字已经存在的情况下 则修改对应的值
# 对象新增数据值
stu2.pwd =123  # 当点的名字不存在的情况下 则新增数据
print(stu1.__dict__)
posted @ 2022-11-02 20:19  魔女宅急便  阅读(46)  评论(0)    收藏  举报
Title