Python高阶基础之面向对象介绍

发布时间 2023-06-27 19:00:41作者: Way*yy

面向过程

'''在支持面向对象的语言中,有两大范式:1、面向过程,2、面向对象'''
# 这两大范式,它是一种编程思想

面想过程:核心就是过程,先做什么>>>>>再做什么>>>>>最后干什么
		即机械式思维方式,类似于流水线工程
举例:
	'把苹果放到冰箱'
    1、打开冰箱
    2、把苹果放进去
    3、关上冰箱门
    这就是一个面向过程的生活案例
    
代码实例:
"""
		# 以注册功能为例:
    	1. 接收用户名和密码
        2. 做逻辑处理,验证参数
        3. 把数据写入到文件里
"""
def get_info():
    user_name = input('请输入账号').strip
    password = input('请输入密码').strip
    return {
        "user_name":user_name
        "password":password
    }
def cheak_info(user_dict):
    flag = False
    if user_dict["user_name"] = '0':
        print("user_name必须输入")
        flag = True
    elif password == '0':
        print("password必须输入")
        flag = True
        return {
            "user_dict":user_dict
            "flag":flag
        }
def sava_info(parm):
    if not parm["flag"]:
        import json
        with open("user_name.txt","w",encode("utf-8")) as f:
            json.dump(parm["user_dict"],f)
            
            
def main():        
    user_dict = get_info()
    parm = cheak_info(user_dict)
    sava_info(parm)
    
if__name__ == '__main__':
    main()
    
    
面向过程:
	优点:将复杂的东西简单化,进而流程化
    缺点:可扩展性太差,有可能牵一发而动全身
    使用场景:对扩展性提要求不太高的地方,一般使用面向过程

面向对象

面型对象的核心是"对象"二字
	在生活中:
    	对象就是"特征"与"技能"的结合体
    在程序中:
    	对象就是盛放"数据"与"方法"的结合体
        # 属性:放到类外面就是变量名,放到类里面就是属性
        # 方法:放到类外面就是功能,放到类里面就是方法
        其实也可以将对象称之为"容器",用来存放东西的地方
面向对象:
	优点:可扩展性更强
    缺点:编程的复杂难度变高了
    使用场景:一般对扩展性要求比较高的地方
"""推导面向对象原理"""
# 学生选课系统
    # 版本一
    stu = {'stu_name': "kevin",
           'stu_age': 18,
           'stu_gender': "meal",
           'stu_course': []
           }

    stu2 = {'stu_name': "kevin2",
            'stu_age': 20,
            'stu_gender': "femeal",
            'stu_course': []
            }


    def chose_course(user_dict, course):
        user_dict['stu_course'].append(course)
        print(f"{user_dict['stu_name']}选择了{course}")


    chose_course(stu, 'python')
    chose_course(stu2, 'Linux')

    # 版本二


    def chose_course(user_dict, course):
        user_dict['stu_course'].append(course)
        print(f"{user_dict['stu_name']}选择了{course}")


    stu = {'stu_name': "kevin",
           'stu_age': 18,
           'stu_gender': "meal",
           'stu_course': [],
           "chose_course": chose_course
           }

    stu["chose_course"](stu, 'pyton')

    # 其实这就是面向对象的底层原理
    
总结来说:
	面向对象:
    核心是"对象"二字
    对象的终极奥义就是将程序"整合"
    对象是"容器",用来盛放数据与功能的
    
    类也是"容器",该容器用来存放同类对象共有的数据与功能

类的定义和对象的产生

# 对象:对象是"容器",用来盛放数据与功能的

"""站在不同的角度,分类的结果也不一样"""

# 类也是"容器",该容器用来存放同类对象共有的数据与功能

所以到底是先有对象还是先有类:
	在生活中:
    	先有对象,再有类
    在程序中:
    	必须先定义类,然后再调用类产生对象
############################################################
# 给学生定义一个属性和方法:
	class Student:
    # school 就是一个属性
    school = 'old bay'

    # 在类里面定义一个方法,在外是函数,在内是方法
    def chose_course(user_dict, course):
        user_dict['stu_course'].append(course)
        print(f"{user_dict['stu_name']}选择了{course}")

    """
        函数如果不调用,会不会调用函数体代码? 不会,
        类呢?

        定义类发生的几件事情?
            1. 类一旦被定义,会立马执行类体代码
            2. 类一旦定义完成,会产生类的名称空间,它会把类中的名字都丢到类的名称空间去
            3. 会把类的名称空间绑定给__dict__属性, 如何查看: 类名.__dict__
    """

    # 查看类的名称空间
    print(Student.__dict__)
    # {'__module__': '__main__', 'school': 'old bay', 'chose_course': <function Student.chose_course at
    # 0x000002C6D2F4C0D0>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute
    # '__weakref__' of 'Student' objects>, '__doc__': None}

    # 如何产生一个对象?
    # 在程序中必须先定义一个类,然后再调用类产生对象
    # 如何调用类?
    # 类名()
    stu = Student()  # 调用类名得到一个stu的对象
    print(stu)  # <__main__.Student object at 0x000002BB07DA3220>

    #  调用类名会产生一个对象自己的名称空间
    # 如何查看对象的名称空间?
    print(stu.__dict__)  # {} 这就是调用类得到的一个空对象

    """每调用一次类,都会产生一个对象,并且产生的对象之间是相互独立的,互补影响的"""
    # 调用类的过程也是实例化的过程,得到的结果就是一个实例
    stu1 = Student()
    # 调用类的过程可以称之为实例化,而stu1就可以称之为实例也就是对象

定制对象自己独有的属性

# 版本3
class Student():
    # school就是一个属性
    school = 'SH'  # 属性就是变量

    # __init__这个函数名不能改名字,必须叫这个名字,一点都不能差
    def __init__(stu_obj, name, age, gender, salary):
        stu_obj.name = name  # stu.__dict__['name'] = 'kevin'
        stu_obj.age = age  # stu.__dict__['age'] = '18'
        stu_obj.gender = gender  # stu.__dict__['gender'] = 'male'
        stu_obj.salary = salary  # stu.__dict__['salary'] = '1800'

    # 在类里面定义一个方法出来,为什么叫方法了呢?本质上就是函数,写在类里面就叫方法
    def choose_course(stu_dict, course, ):
        stu_dict["courses"].append(course)
        print("%s选择了%s成功,%s" % (stu_dict["name"], course, stu_dict["courses"]))

# 怎么得到一个对象
"""
    调用类会自动的触发类里面的__init__方法,然后会把得到的对象本身当成第一个参数自动传递
"""

# stu['choose_course'](stu, 'linux')
stu = Student('kevin', 18, 'male', 2800)  # stu = Student(stu, 'kevin', 18, 'male', 2800)
stu1 = Student('jason', 28, 'male', 3800)
# stu2 = Student()

"""__dict__开头的属性或者方法都有他自己的特殊含义,一般不建议使用"""

print(stu.__dict__)
print(stu1.__dict__)

名字的查找顺序

# 属性的查找顺序分两大类:
类属性:在类里面定义的属性就是类属性
对象属性:就是对象自己独有的属性

'''类属性和对象属性有没有关系呢?有的'''
# 1. 类属性
# 增删改查
# 查看
print(Student.school)
#
#
# # 增加
Student.x = 'a'
Student.y = 'b'
print(Student.__dict__)  # 'x': 'a', 'y': 'b'
# # 改
Student.x = 10
print(Student.__dict__)  # 'x': 10, 'y': 'b'
# # 删除
del Student.school
print(Student.__dict__) # 删除掉Student中的school属性

class Student():
    # school就是一个属性
    school = 'SH'  # 属性就是变量

    # __init__这个函数名不能改名字,必须叫这个名字,一点都不能差
    def __init__(self, name, age, gender):
        self.name = name  # stu.__dict__['name'] = 'kevin'
        self.age = age  # stu.__dict__['age'] = '18'
        self.gender = gender  # stu.__dict__['gender'] = 'male'


stu = Student("kevin", 18, 'make')  # 调用类会自动触发初始化方法__init__ stu = Student(stu, "kevin", 18, 'make')

# 对象属性

print(stu.__dict__)  # {'name': 'kevin', 'age': 18, 'gender': 'make'}
#
# # 查看
print(stu.__dict__['name'])  # kevin
print(stu.__dict__['age'])  # 18
print(stu.__dict__['gender'])  # make
#
print(stu.name)  # kevin
print(stu.age)  # 18
print(stu.gender)  # make
stu.yang = 10
print(stu.__dict__)  # {'name': 'kevin', 'age': 18, 'gender': 'make', 'yang': 10}
# """这是个特殊的:对象属性的查找顺序是:先在自己对象的名称空间中查找,如果找不到再去产生这个对象的类中取找,如果找不到,就报错"""
print(stu.school)  # SH
#
# # 增加
stu.x = 1
print(stu.__dict__)
# {'name': 'kevin', 'age': 18, 'gender': 'make', 'yang': 10, 'x': 1}
# # 改
stu.x = 10
print(stu.__dict__)
# {'name': 'kevin', 'age': 18, 'gender': 'make', 'yang': 10, 'x': 10
# # 删除
del stu.school
print(stu.__dict__)
# 删除属性时会从自己名称空间查找如果有就删除,如果没有就报错

小练习

"""
	1. 定义一个类,产生一堆对象
	2. 定义一个计数器,记录产生了多少个对象
"""

class Student():
    school = 'Sh'
    count = 0
    def __init__(self, name, age, gender):
        """面向对象中,必须搞清楚self是谁"""
        self.name = name
        self.age = age
        self.gender = gender
        Student.count += 1


stu = Student("kevin", 18, 'male')
stu1 = Student("kevin1", 18, 'male')
stu2 = Student("kevin2", 18, 'male')
stu3 = Student("kevin3", 18, 'male')
print(stu.__dict__)  # {'name': 'kevin', 'age': 18, 'gender': 'male'}
print(stu.count) # 4
print(stu1.count) # 4
print(stu2.count) # 4
print(Student.count) # 4
"""注意计数器定义的时候要定义在类的里面,而不是在对象里面"""

选课

# # 版本一
# stu_name = 'kevin'
# stu_age = 18
# stu_gender = 'female'
# set_course = []
#
#
# def choose_courses(stu_name, set_course, course):
#     set_course.append(course)
#     print(f'{stu_name}选了{course}')
#
#
# choose_courses(stu_name, set_course, 'python')
# 缺点:代码太乱而且代码冗余过多,其次可扩展性太差

# 版本二
# user_dict1 = {
#     'school': 'old bay',
#     'stu_name': 'kevin',
#     'stu_age': 18,
#     'stu_gender': 'female',
#     'set_course': [],
#
#
# def choose_courses(new_dict, course):
#     new_dict['set_course'].append(course)
#     print(f"{new_dict.get('stu_name')}选了{course}")
#
#
# choose_courses(user_dict, 'python')
# 优化了代码杂乱无章
# 缺点 :代码冗余、扩展性太差

# 版本三
# def choose_courses(new_dict, course):
#     new_dict['set_course'].append(course)
#     print(f"{new_dict.get('stu_name')}选了{course}")
#
#
# user_dict1 = {
#     'school': 'old bay',
#     'stu_name': 'kevin',
#     'stu_age': 18,
#     'stu_gender': 'female',
#     'set_course': [],
#     'choose_courses': choose_courses
#     # value值的choose_courses就是上面函数的内存地址
# }
# user_dict2 = {
#     'school': 'old bay',
#     'stu_name': 'tank',
#     'stu_age': 20,
#     'stu_gender': 'male',
#     'set_course': [],
#     'choose_courses': choose_courses
# # value值的choose_courses就是上面函数的内存地址

# user_dict1['choose_courses'](user_dict1, 'python')  # kevin选了python
# user_dict2['choose_courses'](user_dict2, 'Linux')  # tank选了Linux
# # 其实上述的调用方法以及存储方法就是面向对象的底层原理啊
# # 优点:方便了很多,只需要每次通过字典就可以直接调用函数,并为其传值
# # 缺点:代码冗余,扩展性差

# 版本四
# class Student:
#     def choose_courses(new_dict, course):
#         new_dict['set_course'].append(course)
#         print(f"{new_dict.get('stu_name')}选了{course}")
#
#     student_school = {
#         'school': 'old bay',
#         'choose_courses': choose_courses
#     }
#
#     user_dict1 = {
#
#         'stu_name': 'kevin',
#         'stu_age': 18,
#         'stu_gender': 'female',
#         'set_course': [],
#         # value值的choose_courses就是上面函数的内存地址
#     }
#     user_dict2 = {
#         'stu_name': 'tank',
#         'stu_age': 20,
#         'stu_gender': 'male',
#         'set_course': []
#     }
#     # value值的choose_courses就是上面函数的内存地址
# 优化:将字典中相同的属性以及方法都拿出来

# 版本五
# class Student:
#     school = 'old_bay'
#
#     def choose_courses(new_dict, course):
#         new_dict['set_course'].append(course)
#         print(f"{new_dict.get('stu_name')}选了{course}")
#
#     # stu = Student()
#     # stu.name = 'kevin'
#     # stu.age = 18
#     # stu.gender = 'female'
#     # stu.course = 'python'
#     # print(stu.__dict__)  # {'name': 'kevin', 'age': 18, 'gender': 'female', 'course': 'python'}
#
#
# stu1 = Student()
# stu2 = Student()
# stu3 = Student()
#
#
# # 每次调用类就会产生一个对象容器,所以现在就产生了stu1、stu2、stu3三个对象
#
#
# def init(stu_obj, name, age, female, course):
#     stu_obj.name = name
#     stu_obj.age = age
#     stu_obj.female = female
#     stu_obj.course = course
#
#
# init(stu1, 'kevin', 18, 'male', 'python', )
# init(stu2, 'tom', 20, 'female', 'Linux')
# init(stu3, 'tank', 30, 'male', 'php')
# print(stu1.__dict__)  # {'name': 'kevin', 'age': 18, 'female': 'male', 'course': 'python'}
# print(stu2.__dict__)  # {'name': 'tom', 'age': 20, 'female': 'female', 'course': 'Linux'}
# print(stu3.__dict__)  # {'name': 'tank', 'age': 30, 'female': 'male', 'course': 'php'}
# # 因此init函数就可以完全代替掉choose_courses函数,
# # 学生们选课只需要调用init函数并输入相对应的信息记好了

# 最终版
class Student:
    school = 'old_bay'  # 所有学生的共同属性

    def __init__(self, name, age, female, course):
        self.name = name
        self.age = age
        self.female = female
        self.course = course


stu1 = Student('kevin', 18, 'male', 'python')
stu2 = Student('tank', 20, 'female', 'Linux')
stu3 = Student('tom', 30, 'male', 'Java')
print(stu1.__dict__)
# {'name': 'kevin', 'age': 18, 'female': 'male', 'course': 'python'}
print(stu2.__dict__)
# {'name': 'tank', 'age': 20, 'female': 'female', 'course': 'Linux'}
print(stu3.__dict__)
# {'name': 'tom', 'age': 30, 'female': 'male', 'course': 'Java'}

# 这样一个既简介扩展性又强的简易查看选课系统就好了