ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python之面向对象基础知识

2022-04-07 02:32:34  阅读:158  来源: 互联网

标签:obj name val person python dog 基础知识 面向对象 print


概要

  • 面向对象编程思想前戏

  • 面向过程编程与面向对象编程

  • 类与对象的概念

  • 代码编写类

  • 代码产生对象

  • 类与对象的具体操作

内容详细

面向对象编程思想前戏

人狗对战小游戏

1.描述人与狗:描述人与狗的方式:使用字典一个个描述

dog 1 = {
    'name':'小黑',
    'type':'田园犬',
    'attack_val':30,
    'life_val':200
}
dog 2 = {
    'name':'小白',
    'type':'恶霸犬',
    'attack_val':180,
    'life_val':500
}
person 1 = {
    'name': '小龙',
    'type':'猛男',
    'attack_val':10,
    'life_val':1000
}

2.这样反复写很麻烦 :我们可以封装成函数 减少代码冗余 所以要定义专门用来描述人与狗的函数(最好单独编写)

def get_person(name, gender, age, t_type, attack_val, life_val):
    data_dict = {
#         'name': name,
#         'gender': gender,
#         'age': age,
#         't_type': t_type,
#         'attack_val': attack_val,
#         'life_val': life_val
#     }
    return data_dict
# p1 = get_person('jason', 'male', 18, '猛男', 800, 1000)
# p2 = get_person('kevin', 'female', 28, '淑女', 5, 100)
# dog1 = get_dog('小黑', '松狮犬', 300, 500)
# dog2 = get_dog('小白', '泰迪犬', 50, 200)
# def dog_attack(dog_obj, person_obj):
#     """
#     :param dog_obj: 接收一条狗
#     :param person_obj: 接收一个人 
        
    

3.使用最简单的掉血逻辑 血量减去对方攻击力

print('当前人的血量是:%s' % person_obj.get('life_val'))
#     person_obj['life_val'] -= dog_obj.get('attack_val')
#     print("""狗:%s 咬了人:%s 一口 人掉血:%s 剩余血量:%s"""%(dog_obj.get('name'),person_obj.get('name'),dog_obj.get('attack_val'),person_obj['life_val']))
# def person_attack(person_obj, dog_obj):
#     """
#     :param person_obj: 接收一个人
#     :param dog_obj: 接收一条狗
#     """
# 		print('当前狗的血量是:%s'%dog_obj.get('life_val'))
#     dog_obj['life_val'] -= person_obj.get('attack_val')
#     print("""人:%s 锤了狗:%s 一下 狗掉血:%s 剩余血量:%s"""%(person_obj.get('name'),dog_obj.get('name'),person_obj.get('attack_val'),dog_obj['life_val']))

4.在括号内调换参数 导致参数混乱 比如人使用狗的技能 狗使用人的技能

# 狗咬人
# dog_attack(dog2,p1)
# print(p1)
# 人锤狗
# person_attack(p2, dog1)
# print(dog1)
'''人调用了狗的攻击动作'''
# dog_attack(p1, dog1)
'''狗调用了人的攻击工作'''
# person_attack(dog2,p2)

如何做到只有人可以调用人的攻击动作 狗调用狗的攻击动作

目的: 其实就是想让人的数据跟人的功能绑定 狗的数据跟狗的功能绑定

方法:将人的攻击动作功能放在产生人的函数数据内

def get_person(name, gender, age, t_type, attack_val, life_val):
    def person_attack(person_obj, dog_obj):
        :param person_obj: 接收一个人
        :param dog_obj: 接收一条狗
         
        print('当前狗的血量是:%s' % dog_obj.get('life_val'))
        dog_obj['life_val'] -= person_obj.get('attack_val')
        print("""人:%s 锤了狗:%s 一下 狗掉血:%s 剩余血量:%s""" % (
        person_obj.get('name'), dog_obj.get('name'), person_obj.get('attack_val'), dog_obj['life_val']))
        
     data_dict = {
        'name': name,
        'gender': gender,
        'age': age,
        't_type': t_type,
        'attack_val': attack_val,
        'life_val': life_val,
        'person_attack':person_attack  # 我们用人的功能来调用人的数据
    }
    return data_dict

def get_dog(name, t_type, attack_val, life_val):
    def dog_attack(dog_obj, person_obj):
        """
        :param dog_obj: 接收一条狗
        :param person_obj: 接收一个人
        """
        # 使用最简答的掉血逻辑  血量减去对方攻击力
        print('当前人的血量是:%s' % person_obj.get('life_val'))
        person_obj['life_val'] -= dog_obj.get('attack_val')
        print("""狗:%s 咬了人:%s 一口 人掉血:%s 剩余血量:%s""" % (
        dog_obj.get('name'), person_obj.get('name'), dog_obj.get('attack_val'), person_obj['life_val']))
    data_dict = {
        'name': name,
        't_type': t_type,
        'attack_val': attack_val,
        'life_val': life_val,
        'dog_attack':dog_attack    # 我们用狗的攻击来调用狗的功能
    }
    return data_dict

5.输入具体的数据 调用人的数据来调用人的功能 调用狗的数据来调用狗的功能 这样就不会造成数据与功能的混乱

p1 = get_person('jason','male',18,'猛男',800, 1000)
p2 = get_person('kevin','female',28,'淑女',10,100)
dog1 = get_dog('小黑', '松狮犬', 300, 500)
dog2 = get_dog('小白', '泰迪犬', 50, 200)
p1['person_attack'](p1,dog1)   # person_attack(p1,dog1)
dog1['dog_attack'](dog1,p2)    #dog_attack(dog1,p2)

6.上述操作其实就是将数据与功能进行绑定

​ 不再是所有的数据都可以调用任意的功能 造成数据与功能的混乱局面

上述将数据与功能整合到一起的操作其实就是 :面向对象编程的思想

编程思想

1.面向过程编程

​ 将程序的执行流程化 即分布操作 分布的过程中降低问题的复杂度 从而解决问题

例如:注册、登录、结算购物车...

注册:第一步获取用户名与密码

​ 第二步比对用户名数据

..............结算:第一步获取购物车数据 第二步是计算金额与数量

过程可以理解成是流水线 面向过程编程可以理解成是在创建一条流水线

2.面向对象编程

​ 核心就是"对象"二字

​ 对象其实就是一个'容器',将数据与功能整合到一起

只要符合上述描述的事物都可以称之为是对象!!!

比如:人狗大战最后的函数内部含有数据与功能 可以称之为面向对象编程

模块文件内含有数据与功能 也可以称之为面向对象编程

综上:仔细想想会发现 在python中一切皆是对象!!!

python针对面向对象编程提供了专门的语法 识别度更高 编写更精简

例如:人、动物、游戏角色

面向过程与面向对象两者没有优劣之分 具体要结合实际情况

甚至在很多时候两者是混合在一起的 思想占据的比例不同而已

类与对象的概念

对象:数据与功能的结合体

类:即类别、种类、等价于诸多对象公有的特征(数据、功能)!!!

比如:在现实生活中

人 对象

一群人 人类

狗 对象

一群狗 犬类

上述中的人类 犬类是用来描述什么的?

就是用来描述多个对象'相同'特征的名词

比如:黄种人、黑种人、白种人都属于人类 但是彼此也有不同的特征

类只能描述出公共的特征!!! 不同的特征应该由对象自己描述

综上:类其实也是对象(数据与功能的结合体):一切皆对象

类与对象的创建

在代码编程中一般先有类再有对象

1.先定义类 后产生对象

学生类:

​ 学生类公共的数据

​ 学生类公共的功能

class Student:
    school = '清华大学'
    def choose_course(self):
        print('学生选课功能')

类体代码无需调用就会执行 会产生类的名称空间

类的语法结构

class 类名:

​ 类体代码

1.class是定义类的关键字 类似于函数的def标志词

2.类名 类似于函数名 但是首字母需要大写 用于区分类与其他的区别

3.类体代码就是存放对象公共数据和功能的地方

公共数据:变量名 = 变量值

公共功能:函数

1查看类的名称空间的方法:双下dict

返回值是一个字典

print(Student.__dict__)

1.1 获取类的公共属性:双下dict[属性名]

类获取类公共的属性有一个简便的方式:采用句点符.

print(Student.__dict__['school']) 
print(Student.__dict__['choose_course'])

# print(Student.school)
print(Student.choose_course)

2.如何产生对象:类名加括号

2.1 类名加括号即可产生一个对象

obj1 = Student()
obj2 = Student()

2.2 对象通过双下dict的结果:是一个空字典

print(obj1.__dict__, obj2.__dict__)
# {} {}

2.3 对象通过点公共属性的结果:会拿到类的公共属性

类可以产生多个对象 然后每个对象可以直接拿到类中公共的属性

print(obj1.school)  # 清华大学
# print(obj2.school)  # 清华大学
# print(obj1.choose_course)  # bound method
# print(obj2.choose_course)  # bound method

2.4 类名.公共属性 = '公共属性修改值' 可以修改名与值的对应关系

print(obj1.school)  # 清华大学
print(obj2.school)  # 清华大学
Student.school = '北京大学' 

Student.__dict__['school'] = '北京大学'  修改名字与值的对应关系

print(obj1.school)  # 北京大学
print(obj2.school)  # 北京大学

对象的实例化

# 学生类
class Student:
    def __init__(self, name, age, gender):
        '''该方法就一个功能>>>:给对象添加独有的数据'''
        self.name = name  # obj.__dict__['name'] = name
        self.age = age  # obj.__dict__['age'] = age
        self.gender = gender  # obj.__dict__['gender'] = gender
        
        # 学生类公共的数据
    school = '清华大学'

    # 学生类公共的功能
    def choose_course(self):
        print('学生选课功能')
        
 # obj1 = Student()  # 空字典 目前对象没有自己独有的属性
# obj2 = Student()  # 空字典 目前对象没有自己独有的属性
# print(obj1.__dict__)  # 大白话就是给字典添加键值对
# print(obj2.__dict__)  # 大白话就是给字典添加键值对
需求:要让每个对象都有自己的值
1.逐步给对象添加独有的数据
# obj1.__dict__['name'] = 'jason'  # obj1.name = 'jason'
# obj1.__dict__['age'] = 18  # obj1.age = 18
# obj1.__dict__['gender'] = 'male'  # obj1.gender = 'male'

# obj2.__dict__['name'] = 'kevin'  # obj2.name = 'kevin'
# obj2.__dict__['age'] = 2  # obj2.age = 28
# obj2.__dict__['gender'] = 'female'  # obj2.gender = 'female'
# print(obj1.__dict__,obj2.__dict__)
# print(obj1.name)  # jason
# print(obj2.name)  # kevin

2.经发现上述步骤,需要反复添加 所以将冗余的添加步骤封装成函数
# def init(obj,name,age,gender):
#     obj.name = name  # obj.__dict__['name'] = name
#     obj.age = age  # obj.__dict__['age'] = age
#     obj.gender = gender  # obj.__dict__['gender'] = gender
# init(obj1,'jason',18,'male')
# init(obj2,'kevin',28,'female')
# print(obj1.name)
# print(obj2.name)

3.因上述数据并没有说明是哪个分类中适合该数据,可能是老师类,是动物类,学生类,还需要将上述的部分我们划分类给特定整合的类中去,所以我们要将上述进行包装放在类中
# obj1 = Student()
# obj2 = Student()
# Student.set_info(obj1,'jason',18,'male')
# Student.set_info(obj2,'kevin',28,'female')
# print(obj1.name)  # jason
# print(obj2.name)  # kevin
4.类中针对给类中的对象创建独有数据的函数名 专门定义了一个固定的方法  利用类来给里面的对象来传对象中独有的参数 符合面向对象的精髓 
# obj1 = Student('jason', 18, 'male')
# obj2 = Student('kevin', 28, 'female')
# print(obj1.__dict__)
# print(obj2.__dict__)

类中的双下init方法会在类中产生对象的时候自动执行类中对象的具体步骤
1.先创建一个没有独有数据的空对象
2.将空对象和类的括号内传入的数据一并交给双下init执行  双下init的第一个参数就是对象本身  __init__(obj,name,age,gender)
3.将创建好的对象自动返回
目的是给我们能够减少代码的编写

针对括号内的第一个形参self其实就是一个普通的变量名而已
只不过该变量名将来专门接收对象用的 所以给它起了个固定的名字叫self

绑定方法

在类中定义的函数默认都是绑定给对象使用的

​ 即对象来调 会自动将对象当做第一个参数传入

class Student:
    school = '清华大学'
    # __init__方法不要自己去调用 
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def func(self):
        print('%s正在调用func方法'%self.name)

    def index(self):
        print('%s正在调用index方法'%self.name)

obj1 = Student('jason', 18)
# print(obj1)
obj2 = Student('kevin', 28)

在调用类中函数 有几个参数就需要传几个参数

# Student.func(123,222)

对象调用类中函数 会将当前调用的对象当做第一个参数自动传入 故为啥能理解了为什么类中所有的函数第一个参数都是self

# obj1.func()
# obj2.func()
# print(obj1.func)
# print(obj2.index)

标签:obj,name,val,person,python,dog,基础知识,面向对象,print
来源: https://www.cnblogs.com/wht488232/p/16110571.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有