• 18.面向对象:类与对象、属性查找、一切皆对象


    • 引子
    • 面向对象编程

    • 类与对象

    • 属性查找

    • 一切皆对象


    • 面向对象编程

      核心是对象二字,对象就是盛放相关数据与功能的容器,也可以说是把数据与功能整合到一起的产物

      基于该思想编写程序就是在创造一个个的容器

      优点:扩展性强()
      缺点:编程的复杂度提升
      应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方
      面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性
    # 一个学生的数据信息:name,age,gender
    name = 'geng'
    age = 18
    gender= 'male'
    
    
    # tell_info 功能
    def tell_info():
        print('my name is %s my age is %s my gender is %s' %(name,age,gender))
    
    tell_info()
    # my name is geng my age is 18 my gender is male
    
    # 此时若想执行查看个人信息的功能,需要同时拿来两样东西,一类是功能,另外一类则是数据,然后才能执行,非常麻烦
        
           
    # 把数据和功能整合放到一个容器中,在增加多个学生信息    
    def tell_info(student):
        print('my name is %s my age is %s my gender is %s' %(student["name"],student["age"],student["gender"]))
        
    student = {
        "school":"上海校区",      
        "name":"geng",
        "age":18,
        "gender":"male",
        "tell_info":tell_info
    }
    
    student["tell_info"](student)
    
    
    student1 = {
        "school":"上海校区",
        "name":"yang",
        "age":19,
        "gender":"female",
        "tell_info":tell_info
    }
    
    student1["tell_info"](student1)
    
    
    # 可以看出两个容器有相同的地方,只有是同一类才能总结出相似的东西
    

    • 类与对象

      类即类别、种类,是面向对象设计最重要的概念,对象是数据与功能的容器,而类则是一系列对象相似的数据与功能的容器

      那么问题来了,先有的一个个具体存在的对象(比如一个具体存在的人),还是先有的人类这个概念,这个问题需要分两种情况去看

      在现实世界中:先有对象,再有类
      在程序中:务必保证先定义类,后产生对象

      这与函数的使用是类似的,先定义函数,后调用函数,类也是一样的,在程序中需要先定义类,后调用类

      不一样的是,调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象

    • 定义类发生的事

      1、会立刻运行类体代码
      2、将运行过程中产生的名字都丢到类的名称空间中
    class Student:  # 类的命名应该使用“驼峰体”
        school = "上海校区"  # 数据
    
        def tell_info(student): # 功能
            print('my name is %s my age is %s my gender is %s' % (student["name"], student["age"], student["gender"]))
    
    # 类体最常见的是变量的定义和函数的定义,但其实类体可以包含任意Python代码,类体的代码在类定义阶段就会执行,
    # 因而会产生新的名称空间用来存放类中定义的名字,可以打印Student.__dict__来查看类这个容器内盛放的东西
    
    # print(Student.__dict__)
    
    • 调用类发生的事情

      1、创造一个对象的字典,用来存放对象独有的数据
      2、将对象与类建立好关联
    class Student:
        school = "上海校区"  # 共有数据
    
    obj1 = Student()  # 每实例化一次Student类就得到一个学生对象
    obj2 = Student()
     #该方法会在对象产生之后自动执行,专门为对象进行初始化操作,可以有任意代码,但一定不能返回非None的值
    def init(self,x,y,z):
        self.name = x
        self.age = y
        self.gender = z
    
    init(obj1,"geng",18,"male")  # 重新实例学生
    init(obj2,"yang",19,"female")
    
    # 至此,我们造出了两个对象与一个类,对象存放各自独有的数据,类中存放对象们共有的内容
    
    print(obj1.__dict__)
    # {'name': 'geng', 'age': 18, 'gender': 'male'}
    
    print(obj2.__dict__)
    # {'name': 'yang', 'age': 19, 'gender': 'female'}
    
    print(Student.__dict__)
    # {'__module__': '__main__', 'school': '上海校区', '__dict__': <attribute '__di
    
    • 调用类的过程

      1、先创造一个空对象
      2、自动触发类内的__init__函数的运行,将空对象当做第一个参数自动传入
      3、返回一个初始化好的对象给obj1
    class Student:
        school = "上海校区"
        #            空对象, "egon", 18, "male"
        def __init__(self, x, y, z):
            self.name = x  # 空对象.name = "egon"
            self.age = y   # 空对象.age = 18
            self.gender = z  # 空对象.gender = "male"
    
        def tell_info(student):
            print('my name is %s my age is %s my gender is %s' % (student["name"], student["age"], student["gender"]))
    
    
    obj1 = Student("egon",18,"male")  # Student.__init__(空对象,"egon",18,"male")
    obj2 = Student("tom",19,"female")
    
    
    print(obj1.__dict__)
    print(obj2.__dict__)
    print(Student.__dict__)
    
    

    • 属性查找

      对象的名称空间里只存放着对象独有的属性,而对象们相似的属性是存放于类中的。对象在访问属性时,会优先从对象本身的__dict__中查找,未找到,则去类的__dict__中查找
    class Student:
        school = "上海校区"
        #            空对象, "egon", 18, "male"
        def __init__(self, x, y, z):
            self.name = x  # 空对象.name = "egon"
            self.age = y   # 空对象.age = 18
            self.gender = z  # 空对象.gender = "male"
    
        def tell_info(self):
            print('my name is %s my age is %s my gender is %s' % (self.name, self.age, self.gender))
    
    
        def func(self):
            pass
    
    obj1 = Student("egon",18,"male")
    obj2 = Student("tom",19,"female")
    
    # 对象.属性的查找顺序: 先从对象的字典里找,再从类的字典里找
    
    print(obj1.name)  # obj1.__dict__["name"]
    print(obj1.school)
    print(obj1.tell_info)
    
    obj1.school = "XXX"
    print(obj1.school)  # xxx 说明优先从对象字典里找
    
    
    # 类.属性:从类自己的字典里找(类中属性之所以可以自己调,其实是因为类的属性是为对象准备的)
    print(Student.school)
    print(Student.__init__)
    print(Student.tell_info)
    
    # 类中的数据属性是直接共享给所有对象用的,指向相同的内存地址
    Student.school = 'XXXXX'
    obj1.school = 'YYYYY'
    print(Student.school,id(Student.school)) # 上海校区 1994529963920
    print(obj1.school,id(Student.school))    # 上海校区 1994529963920
    print(obj2.school,id(Student.school))    # 上海校区 1994529963920
    
    
    # 类中的函数类可以可用,如果类来调用就是一个普通函数,该怎么传参就怎么传
    # 但其实类中的函数是给对象用,对象来调用就是一个绑定方法,绑定方法的特点是会将调用当做第一个参数自动传入
    print(Student.tell_info)
    Student.tell_info(obj1)
    Student.tell_info(obj2)
    
    print(obj1.tell_info)
    obj1.tell_info()
    obj2.tell_info()
    
    Student.func()
    obj1.func()
    
    • 一切皆对象(补充概念)

    • 说python中一切皆对象,所有的东西全都是对象。在python3当中统一了类型与类的概念,如整型、浮点型、列表、字典、元组等这都是类型,一个类型可以称之为一个类,类就等同于类型

    # 自定义类型:Student
    
    class Student:
        n = 0
    
        def __init__(self, name, age, gender):
            Student.n += 1
            self.name = name
            self.age = age
            self.gender = gender
    
        def choose(self):  # self = obj1
            print('hello %s' %self.name)  # obj1.name
    
    
    obj1 = Student("egon1", 18, "male")
    print(type(obj1))  # 查看对象的类型
    # <class '__main__.Student'>
    print(Student)     # 查看类跟对象类型一样,说明类等同于类型
    # <class '__main__.Student'>
    print(list)
    # <class 'list'>
    
    obj1.choose()
    # hello egon1
    Student.choose(obj1)
    # hello egon1
    
    # 内置类型:list
    l1 = list([1,2,3])
    # print(l1)
    # l1.append(4)
    list.append(l1,4)
    print(l1)
    
  • 相关阅读:
    .Net Mvc学习——ASP.NET MVC中常用的ActionResult类型
    Html+Ajax+Webservice 实现文件跨域上传
    H5移动端实现图片上传
    Jquery中$("").事件()和$("").on("事件","指定的元素",function(){});的区别(jQuery动态绑定事件)
    第四周 利用嵌入式汇编调用系统调用
    Junit的简单使用
    第三周 内核调试
    checkstyle findbugs以及sourcemonitor的使用
    第二周 内核进程调度
    重新打理博客
  • 原文地址:https://www.cnblogs.com/gfeng/p/14253041.html
Copyright © 2020-2023  润新知