Python教程

python之面向对象基础知识

本文主要是介绍python之面向对象基础知识,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

概要

  • 面向对象编程思想前戏

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

  • 类与对象的概念

  • 代码编写类

  • 代码产生对象

  • 类与对象的具体操作

内容详细

面向对象编程思想前戏

人狗对战小游戏

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)
这篇关于python之面向对象基础知识的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!