首页 > 编程语言 >面向对象编程

面向对象编程

时间:2023-03-25 19:56:12浏览次数:32  
标签:__ name courses stu dict 面向对象编程 print

目录

python中的两大编程思想

面向过程

面向过程的核心是:过程二字。过程是先干什么,再干什么,最后干什么的流程,也就是机械化的思维方式,面向过程就是按照固定的流程解决问题。

面向过程是提出问题,然后制定出问题的解决方案。就是需要列举出每一步的流程,并且会随着步骤的深入,问题的解决越来越简单。

列举一个生活中的例子:把大象放进冰箱需要分几步? 1.打开冰箱门, 2.把大象放进冰箱, 3.关上冰箱门

优点:把复杂的问题简单化,进而流程化
缺点:扩展性差
使用场景:对扩展性要求不高的地方

'''
之前学习截止ATM为止,使用的几乎都是面向过程编程

  eg:注册功能、登录功能、转账功能
'''

# 注册功能分布封装成函数
# 1. 接收用户输入的用户名和密码
def get_info():
    username = input('username:')
    password = input('password')
    email = input('email:')

    return {
        'username': username,
        'password': password,
        'email':email
    }


# 2. 验证参数
def check_info(userinfo):
    # userinfo = {
    #         'username': username,
    #         'password': password
    #     }
    flag = False
    if len(userinfo['username']) == 0:
        print('username不能为空')
        flag = True
    if len(userinfo['password']) == 0:
        print('password不能为空')
        flag = True
    if len(userinfo['email']) == 0:
        print('email不能为空')
        flag = True
    return {
        'flag':flag,
        'userinfo':userinfo
    }


# 3. 写入文件
def save_info(param):
    if not param['flag']:
        '''写文件'''
        with open('a.txt', 'w', encoding='utf-8') as f:
            import json
            json.dump(param['userinfo'], f)



def main():
    userinfo = get_info()
    param = check_info(userinfo)
    save_info(param)


if __name__ == '__main__':
    main()

面向对象

“面向对象”的核心是“对象”二字,而对象的精髓在于“整合“,什么意思?

所有的程序都是由”数据”与“功能“组成,因而编写程序的本质就是定义出一系列的数据,然后定义出一系列的功能来对数据进行操作。在学习”对象“之前,程序中的数据与功能是分离开的,如下

# 数据:name、age、sex
name='lili'
age=18
sex='female'
 
# 功能:tell_info
def tell_info(name,age,sex): 
    print('<%s:%s:%s>' %(name,age,sex))
 
# 此时若想执行查看个人信息的功能,需要同时拿来两样东西,一类是功能tell_info,另外一类则是多个数据name、age、sex,然后才能执行,非常麻烦
tell_info(name,age,sex)

在学习了“对象”之后,我们就有了一个容器,该容器可以盛放数据与功能,所以我们可以说:对象是把数据与功能整合到一起的产物,或者说”对象“就是一个盛放数据与功能的容器/箱子/盒子。

在了解了对象的基本概念之后,理解面向对象的编程方式就相对简单很多了,面向对象编程就是要造出一个个的对象,把原本分散开的相关数据与功能整合到一个个的对象里,这么做既方便使用,也可以提高程序的解耦合程度,进而提升了程序的可扩展性(需要强调的是,软件质量属性包含很多方面,面向对象解决的仅仅只是扩展性问题)

两种编程思想的分析

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

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

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

面向对象的推导

面向对象对于初学者而言是一个非常抽象的东西,直接讲解晦涩难懂,浅尝辄止!

python中一切皆对象>>>:都是数据和功能的整合

我们先编写一个学生选课系统

步骤1:定义学生和选课功能

代码定义出学生信息和选课,直接使用变量和函数

stu_name = 'kevin'
stu_age = 20
stu_gender = 'male'
stu_courses = []

stu1_name = 'tony'
stu1_age = 21
stu1_gender = 'female'
stu1_courses = []

# 选课的功能:谁,选择的课程(可一可多,以列表储存),课程
def choose_course(stu_name, stu_courses, course):
    stu_courses.append(course)
    print('%s选课成功%s' % (stu_name, stu_courses))

choose_course(stu_name, stu_courses, 'python')
# > kevin选课成功['python']
choose_course(stu1_name, stu1_courses, 'linux')
# > tony选课成功['linux']
'''上述的学生信息还比较少,如果学生人数变多了,有几百个,或者不同学生的信息都混合在一起时,想要找出一个学生的信息就变得难上加难'''

步骤2:信息字典

将学生的信息放到一个字典中,选课功能函数的参数随之变化

stu1 = {
    'name': 'kevin',
    'age': 20,
    'gender': 'male',
    'courses': [],
}
stu2 = {
    'name': 'tony',
    'age': 21,
    'gender': 'female',
    'courses': []
}
def choose_course(stu_dict, course):
    stu_dict['courses'].append(course)
    print('%s选课成功%s' % (stu_dict['name'], stu_dict['courses']))

choose_course(stu1, 'python')
choose_course(stu2, 'linux')
# > kevin选课成功['python']
# > tony选课成功['linux']
'''面向对象中的对象是特征和技能的结合体,上述定义的学生,只有特征,没有技能,所以要将选课功能也加入进去,才能够组成一个对象'''

步骤3:数据与功能的绑定

将选课的功能跟学生的信息绑定,>>>:数据与功能的绑定

def choose_course(stu_dict, course):
    stu_dict['courses'].append(course)
    print('%s选课成功%s' % (stu_dict['name'], stu_dict['courses']))

stu1 = {
    'name': 'kevin',
    'age': 20,
    'gender': 'male',
    'courses': [],
    'choose_courses': choose_course
}

stu2 = {
    'name': 'tony',
    'age': 21,
    'gender': 'female',
    'courses': [],
    'choose_courses': choose_course
}

stu1['choose_courses'](stu1, 'python')
stu2['choose_courses'](stu2, 'linux')
# > kevin选课成功['python']
# > tony选课成功['linux']
'''调用方式改变了,谁来调用这个方法,会将自己当成参数传进去'''

类与对象

类即类别/种类,是面向对象分析和设计的基石,如果多个对象有相似的数据与功能,那么该多个对象就属于同一种类。有了类的好处是:我们可以把同一类对象相同的数据与功能存放到类里,而无需每个对象都重复存一份,这样每个对象里只需存自己独有的数据即可,极大地节省了空间。所以,如果说对象是用来存放数据与功能的容器,那么类则是用来存放多个对象相同的数据与功能的容器。

综上所述,虽然我们是先介绍对象后介绍类,但是需要强调的是:在程序中,必须要事先定义类,然后再调用类产生对象(调用类拿到的返回值就是对象)。产生对象的类与对象之间存在关联,这种关联指的是:对象可以访问到类中共有的数据与功能,所以类中的内容仍然是属于对象的,类只不过是一种节省空间、减少代码冗余的机制,面向对象编程最终的核心仍然是去使用对象。

对象:'特征'与'技能'的结合体
类:一系列相似特征与相似技能的结合体

面向对象编程

类的语法结构

 """
    专业语法来定义类
    语法格式:
        def index():
            pass
        class 类名():
            pass
"""
  1. 类名的命名遵循变量的命名规范
  2. 类名的首字母一般大写
  3. 如果类名存在多个单词,一般是大驼峰格式

我们还可以定义一个空类

class Student():
    pass

定义类发生的几件事情?

  1. 定义类,会立马执行类体代码
  2. 产生类的名称空间,并且把类中的属性和方法名字丢在类的名称空间中,其实就是丢在大字典里
  3. 把类的名称空间绑定给__dict__,类名.dict

类的定义与实例化

简单介绍基于面向对象的思想如何编写程序

# 类名后可以不加括号(后续学习),但是推荐加上括号
class Student():
    # 定义一个特征---->变量
    school = 'SH'  # 属性:变量名与数据值的绑定
    country = 'China'  # 变量在类里面叫属性

    # 定义功能---->函数
    # 函数写到类里面叫方法
    def choose_course(stu_dict, course):
        stu_dict['courses'].append(course)
        print('%s选课成功%s' % (stu_dict['name'], stu_dict['courses']))

类体最常见的是变量的定义和函数的定义,但其实类体可以包含任意Python代码,类体的代码在类定义阶段就会执行,因而会产生新的名称空间用来存放类中定义的名字,可以打印Student.__dict__来查看类这个容器内盛放的东西

print(Student.__dict__)
# > 输出结果是:
# {'__module__': '__main__', 
# 'school': 'SH',   # 属性:值
# 'country': 'China',   # 属性:值
# 'choose_course': <function Student.choose_course at 0x000001C49957FD08>,   # 方法:内存地址
# '__dict__': <attribute '__dict__' of 'Student' objects>,
# '__weakref__': <attribute '__weakref__' of 'Student' objects>,
# '__doc__': None}

先定义类,调用类产生对象。调用类的过程称为将类实例化,拿到的返回值就是程序中的对象,或称为一个实例

'''类名加括号就会产生对象 并且每执行一次都会产生一个全新的对象'''
# 变量名stu1接收类名加括号之后的返回值(结果)
stu1 = Student()  # 类名()  对象1
stu2 = Student()  # 类名()  对象2

打印对象, 得到一个地址, 是Student类产生的对象

print(stu1)  # > <__main__.Student object at 0x000001CB32F3D470>
print(stu2)  # > <__main__.Student object at 0x000001E756659B00>

对象也有自己的名称空间

print(stu1.__dict__) # {} 
print(stu2.__dict__) # {}  
'''调用类产生对象,得到的对象就是一个空对象,空字典'''

定制对象自己独有的属性

对象属性的推导流程

推导流程1:每个对象手动添加独有的数据, 想要往对象名称空间中加变量,就是直接往字典里面加值

# 添加第一个对象的属性
stu1.__dict__['name'] = 'kevin'  # 新增键值对
stu1.__dict__['age'] = 20
stu1.__dict__['gender'] = 'male'
stu1.__dict__['courses'] = []

print(stu1.__dict__)
# > {'name': 'kevin', 'age': 20, 'gender': 'male', 'courses': []}

# 添加第二个对象的属性
stu2.__dict__['name'] = 'tom'  
stu2.__dict__['age'] = 28
stu2.__dict__['gender'] = 'fmale'
stu2.__dict__['courses'] = []
print(obj2.__dict__)

在面向对象中,类和对象访问数据或者功能,可以统一采用句点符。以上可以直接写成

stu = Student()
stu.name = 'kevin'      # stu.__dict__['name'] = 'kevin'
stu.age = 20            # stu.__dict__['age'] = 20
stu.gender = 'male'     # stu.__dict__['gender'] = 'male'
stu.courses = []        # stu.__dict__['courses'] = []


print(stu.__dict__)
# > {'name': 'kevin', 'age': 20, 'gender': 'male', 'courses': []}

# 建其他对象
stu1 = Student()
stu1.name = 'jack'
stu1.age = 21
stu1.gender = 'male'
stu1.courses = []
print(stu1.__dict__)
# > {'name': 'jack', 'age': 21, 'gender': 'male', 'courses': []}
stu2 = Student()
stu2.name = 'tom'   
stu2.age = 22
stu2.gender = 'male'
stu2.courses = []
print(stu2.__dict__)
# > {'name': 'tom', 'age': 22, 'gender': 'male', 'courses': []}
'''代码冗余,可以封装成函数'''

推导流程2:封装成函数版本,将内部的值,直接当成参数传输进来,并且,对象名可以当成参数传输进来

stu = Student()
stu1 = Student()
stu2 = Student()

def init(stu_dict, name, age, gender, course=[]):
    stu_dict.name = name
    stu_dict.age = age
    stu_dict.gender = gender
    stu_dict.courses = course

init(stu, 'kevin', 20, 'male')
init(stu1, 'kevin1', 21, 'male')
init(stu2, 'kevin2', 22, 'male')

print(stu.__dict__)
print(stu1.__dict__)
print(stu2.__dict__)
# > {'name': 'kevin', 'age': 20, 'gender': 'male', 'courses': []}
# > {'name': 'kevin1', 'age': 21, 'gender': 'male', 'courses': []}
# > {'name': 'kevin2', 'age': 22, 'gender': 'male', 'courses': []}
'''每一次调用对象都要使用init函数,不想使用这种方法,怎么优化?'''

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

class Student():
    # 定义一个特征
    school = 'SH'  # 属性
    country = 'China'

    # 初始化方法,当类被加括号调用的时候,会自动触发这个函数的执行
    '''即是:类被调用的时候,__init__函数把对象自己当成第一个参数传给了第一个位置形参'''
    def __init__(self, name, age, gender, course=[]):
        # self => stu
        # self => stu1
        self.name = name
        self.age = age
        self.gender = gender
        self.courses = course

    # 函数写到类里面叫方法
    def choose_course(stu_dict, course):
        stu_dict['courses'].append(course)
        print('%s选课成功%s' % (stu_dict['name'], stu_dict['courses']))

'''类被调用的时候,类里面传的第一个参数是这个类产生的对象'''
stu = Student('kevin', 20, 'male')  # stu = Student(stu, 'kevin', 20, 'male')
print(stu.__dict__)
# > {'name': 'kevin', 'age': 20, 'gender': 'male', 'courses': []}
stu1 = Student('kevin1', 21, 'male')  # stu = Student(stu, 'kevin', 20, 'male')
print(stu1.__dict__)
# > {'name': 'kevin1', 'age': 21, 'gender': 'male', 'courses': []}

__init__函数在类里面可有可无,但是想要传参数,就一定要有。谁来调用,就会先把自己当成第一个参数传进去

属性的查找顺序

类属性的查找

查找: 类名.属性名

print(Student.school)
print(Student.country)
print(Student.country1) # 不存在会报错

增加:增加就是赋值

Student.aaa = 'xxx'  # 类中不存在的属性
print(Student.__dict__)

修改

Student.school = 'beijing'  # 类种存在的属性
print(Student.__dict__)

删除

del Student.school
print(Student.__dict__)

对象属性的查找

先产生一个对象

stu = Student('kevin', 20, 'male')  # 产生一个对象
print(stu.__dict__)  # 对象的名称空间

查看

print(stu.__dict__['name']) 
print(stu.name)  

print(stu.age)  # 查看对象自己的属性
print(stu.gender)

print(stu.school)
print(stu.__dict__['school'])  # 先从对象自己的属性里面去查找,没有去类中查找,再没有则直接报错

# stu.school = 'aaaaa'  # 这个属于对象属性的增加,增加的school是在对象名称空间中

'''对象的属性查找,先从自己对象属性里面去找,如果找到了,直接返回,如果找不到,在去产生这个对象的类中取查找,如果也没有,则报错'''

增加

stu.aaa = 'xxx'
print(stu.__dict__)

修改

stu.name = 'xxxx'
print(stu.__dict__)

删除

del  stu.name
print(stu.__dict__)

练习

定义一个计数器,记录一共产生了多少个对象?

class Student():
    school = 'SH'
    count = 0
    def __init__(self, name, age):
        self.name = name
        self.age = age
        # self.count += 1
        Student.count+=1

stu = Student('kevin', 20)
stu1 = Student('kevin1', 21)
stu2 = Student('kevin2', 22)
stu3 = Student('kevin3', 23)
'''类属性一改,对象在调用的时候全改'''
print(Student.count)
print(stu.count)
print(stu.__dict__)
print(stu1.__dict__)
print(stu2.__dict__)
print(stu3.__dict__)

小结

在上述介绍类与对象的使用过程中,我们更多的是站在底层原理的角度去介绍类与对象之间的关联关系,如果只是站在使用的角度,我们无需考虑语法“对象.属性"中”属性“到底源自于哪里,只需要知道是通过对象获取到的就可以了,所以说,对象是一个高度整合的产物,有了对象,我们只需要使用”对象.xxx“的语法就可以得到跟这个对象相关的所有数据与功能,十分方便且解耦合程度极高。

标签:__,name,courses,stu,dict,面向对象编程,print
From: https://www.cnblogs.com/zjyao/p/17255455.html

相关文章

  • 大爽Python入门教程 7-6 面向对象编程 实例演示 简易方格游戏(二维)
    大爽Python入门公开课教案点击查看教程总目录1介绍将上一节,一维的面板拓展成二维的。面板数据从txt中读取出来玩家从左上进入,输入一串移动命令,展示中间过程玩家......
  • Python——面向对象编程(十一)
    1.对象的封装#coding=utf-8#对象的封装#类的概念"""类的名字:当名字由多个单词构成时,我们采用驼峰命名法就是说多个单词,每个单词的首字母需要大写这也是python的......
  • 0316-0322面向对象编程
    0316-0322面向对象编程1.面向过程、对象概念#python中两大范式:1.面向过程2.面向对象'''两者都不是新的技术,而是做事的思维方式'''#面向过程的核心是过程:即按先后次......
  • python - 面向对象编程
    一、对象与过程的概念python中的两大范式:1.面向过程2.面向对象他们两个都不是新的技术,而是一种做事的思维方式1.面向过程:根据业务逻辑从上到下写垒代码面向过程核心是......
  • python入门学习-2.特性、函数、面向对象编程、文件读写
    高级特性切片取一个list或tuple的部分元素>>>L=['Michael','Sarah','Tracy','Bob','Jack']笨方法:>>>[L[0],L[1],L[2]]['Michael','Sarah','Tracy']切......
  • C# 面向对象编程(OOP)
    C#面向对象编程(OOP)C#是面向对象的编程语言,对象就是面向对象程序设计的核心。所谓对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个......
  • Python面向对象编程
    面向对象是思想面向对象是一种编程范式(常见编程范式有命令式,生命石(分领域特定和函数式),面向对象编程,反省计算,元变成,默认并发,拼接式,符号式,基于知识,多范式)语法原生支持面向......
  • 面向对象编程
    1、面向对象编程1、特点封装:让使用对象的人不考虑内部实现,只考虑功能使用把内部的代码保护起来,只留出一些api接口供用户使用继承:就是为了代码的复用,从父类上继承出一......
  • 16.Rust的面向对象编程特性
    面向对象编程(Object-OrientedPrograming,OOP)是一种程序建模的方法。一、面向对象语言的特性编程社区对面向对象语言的特性没有一个共识性的结论。但是对Rust来说,面向对......
  • 面向对象编程
    6.1面向对象编程相关概念6.1.1什么是面向对象编程面向对象编程——ObjectOrientedProgramming,简称OOP,是一种程序设计思想。在该思想中程序里万物都是对象。OOP把对......