• 面向对象编程-类


    day 21

    一、面向对象概述

    1、什么是面向对象:

    1、面向过程的程序设计:

      面向过程,核心是过程,即解决问题的步骤,编写程序好比在设计一条流水线,为了得到合格的产品(程序),人为指定程序需要翔安什么再干什么。它是一种机械式的思维方式。

      优点:将复杂的问题流程化,进而简单化(将一个复杂的问题,拆分成一个个小的问题去实现,实现小的步骤就会变得比较简单。)

      缺点:可扩展性差(解决问题的指向性比较强,若需求有所变动,修改幅度较大)

      使用场景:对扩展性要求较低的软件,比如系统内核,脚本程序(运维工程师写的程序,其目的就是安装一堆软件),Apache HTTP服务器等; 当我们要开发的程序需非常高的扩展性时就不能再使用该方式了

    2、面向对象的程序设计:

      面向对象:核心为对象二字,对象即特征与技能的结合体,基于面向对象的程序设计就好比在创造一个世界,而编写程序的人就相当于是这个世界的上帝,存在的一切皆为对象,不存在的也可以被创造出来,与面向过程机械的思维方式形成鲜明的对比,面向对象更加注重对现实世界的模拟,是一种“上帝式”的思维方式。

      优点:a、可扩展性强(对某一个对象的单独修改,会立刻反映到整个体系中,例如在游戏中对人物参数特性和技能的修改都会变得很容易。);

           b、各个对象之间的耦合度较低,当其中一个对象出现了问题,不会对其他对象产生影响。

      缺点:a、编程的复杂程度高于面向过程;

           b、无法预知执行结果。

      使用场景:需要较高的可扩展性时使用(直接与用户发生交互的程序,如qq,微信);对不需要较高扩展性的程序而言,使用面向对象反而增加了复杂度。

    2、为什么要使用面向对象:

      在开发一些需要与用户直接打交道的程序时,因用户的需求是不停的发生变化,所以我们要使用可扩展性较高的面向对象式编程(本质就是使用不同的对象来编写程序)方式来编写程序。

    二、类与对象:

    1、类:

      类十一个抽象的概念,类即种类、类别,是面向对象设计的重要概念,是一系列的对象的相同特征和技能的结合体。

      注:现实世界中是先有对象,再有类的概念。

        程序中是先定义类,然后在通过调用类来产生对象。

    2、对象:

      对象是通过调用类来产生获得的,因此调用类的过程又称为类实例化的过程。调用类会得到一个返回值,该返回值就是类的一个具体存在的对象(实例)。

    #在程序中,务必保证:先定义(类),后使用(产生对象)
    PS:
      1. 在程序中特征用变量标识,技能(方法)用函数标识
      2. 因而类中最常见的无非是:变量(特征)和函数(方法)的定义
    ​
    #程序中的类
    class OldboyStudent:
        school='oldboy'
        def learn(self):
            print('is learning')
            
        def eat(self):
            print('is eating')
        
        def sleep(self):
            print('is sleeping')
    ​
    #注意:
      1.类中可以有任意python代码,这些代码(函数体类的代码仍然存放在内存中,调用时才会执行)在类定义阶段便会执行
      2.因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过OldboyStudent.__dict__查看
      3.对于经典类来说我们可以通过该字典操作类名称空间的名字(新式类有限制),但python为我们提供专门的.语法
      4.点是访问属性的语法,类中定义的名字,都是类的属性
      5.类本省就是一个容器类型(名称空间),用来存放名字,这是类的用途之一。
    #程序中类的用法
    .:专门用来访问属性,本质操作的就是__dict__
    OldboyStudent.school #等于经典类的操作OldboyStudent.__dict__['school']
    OldboyStudent.school='Oldboy' #等于经典类的操作OldboyStudent.__dict__['school']='Oldboy'
    OldboyStudent.x=1 #等于经典类的操作OldboyStudent.__dict__['x']=1
    del OldboyStudent.x #等于经典类的操作OldboyStudent.__dict__.pop('x')
    ​
    ​
    #程序中的对象
    #调用类,或称为实例化,得到对象
    s1=OldboyStudent()
    s2=OldboyStudent()
    s3=OldboyStudent()
    ​
    #如此,s1、s2、s3都一样了,而这三者除了相似的属性之外还各种不同的属性,这就用到了__init__
    #注意:该方法是在对象产生之后才会执行,只用来为对象进行初始化操作,可以有任意代码,但一定不能有返回值
    class OldboyStudent:
        ......
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
        ......
    ​
    ​
    s1=OldboyStudent('李坦克','',18) #先调用类产生空对象s1,然后调用OldboyStudent.__init__(s1,'李坦克','男',18)
    s2=OldboyStudent('王大炮','',38)
    s3=OldboyStudent('牛榴弹','',78)
    ​
    ​
    #程序中对象的用法
    #执行__init__,s1.name='牛榴弹',很明显也会产生对象的名称空间
    s2.__dict__
    {'name': '王大炮', 'age': '', 'sex': 38}
    ​
    s2.name #s2.__dict__['name']
    s2.name='王三炮' #s2.__dict__['name']='王三炮'
    s2.course='python' #s2.__dict__['course']='python'
    del s2.course #s2.__dict__.pop('course')

    三、属性查找:

      类的两种属性分别为数据属性和函数属性

      1、类的数据属性:所有对象共享

      2、类的函数属性:绑定给对象使用

      注:属性查找的顺序:obj对象产生后自己会生成一块新的内存空间,obj需要调用属性是首先会先从自己的空间中进行查找,如果找不到就会到类的空间中去找,如果找不到就会到父类的空间中去找....最后找不到抛出异常。

    #类的数据属性是所有对象共享的,id都一样
    print(id(OldboyStudent.school))
    print(id(s1.school))
    print(id(s2.school))
    print(id(s3.school))
    '''
    4377347328
    4377347328
    4377347328
    4377347328
    '''#类的函数属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都是不一样
    #ps:id是python的实现机制,并不能真实反映内存地址,如果有内存地址,还是以内存地址为准
    print(OldboyStudent.learn) #0x1021329d8
    print(s1.learn)            #0x1021466d8
    print(s2.learn)            #0x102146710
    print(s3.learn)            #0x102146748
    '''
    <function OldboyStudent.learn at 0x1021329d8>
    <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x1021466d8>>
    <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146710>>
    <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146748>>
    '''

    四、类中的初始化函数

      __ init__函数用于初始化对象,它会在对象刚被创建时自动执行,并传入调用时传递的参数,第一个参数表示要初始化的对象本身。

      注:调用类时发生的两件事:

        a、创建一个空对象stu;

        b、自动触发类中的init功能的执行,并将空对象stu和调用类似括号中传入的参数一同传入。

    #方式一、为对象初始化自己独有的特征
    class People:
        country='China'
        x=1
        def run(self):
            print('----->', self)
    ​
    # 实例化出三个空对象
    obj1=People()
    obj2=People()
    obj3=People()
    ​
    # 为对象定制自己独有的特征
    obj1.name='egon'
    obj1.age=18
    obj1.sex='male'
    ​
    obj2.name='lxx'
    obj2.age=38
    obj2.sex='female'
    ​
    obj3.name='alex'
    obj3.age=38
    obj3.sex='female'# print(obj1.__dict__)
    # print(obj2.__dict__)
    # print(obj3.__dict__)
    # print(People.__dict__)
    #方式二、为对象初始化自己独有的特征
    class People:
        country='China'
        x=1
        def run(self):
            print('----->', self)
    ​
    # 实例化出三个空对象
    obj1=People()
    obj2=People()
    obj3=People()
    ​
    # 为对象定制自己独有的特征
    def chu_shi_hua(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male'
        obj.name = x
        obj.age = y
        obj.sex = z
    ​
    chu_shi_hua(obj1,'egon',18,'male')
    chu_shi_hua(obj2,'lxx',38,'female')
    chu_shi_hua(obj3,'alex',38,'female')
    ​
    ​
    ​
    ​
    ​
    #方式三、为对象初始化自己独有的特征
    class People:
        country='China'
        x=1def chu_shi_hua(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male'
            obj.name = x
            obj.age = y
            obj.sex = z
    ​
        def run(self):
            print('----->', self)
    ​
    ​
    obj1=People()
    # print(People.chu_shi_hua)
    People.chu_shi_hua(obj1,'egon',18,'male')
    ​
    obj2=People()
    People.chu_shi_hua(obj2,'lxx',38,'female')
    ​
    obj3=People()
    People.chu_shi_hua(obj3,'alex',38,'female')
    ​
    ​
    ​
    ​
    # 方式四、为对象初始化自己独有的特征
    class People:
        country='China'
        x=1def __init__(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male'
            obj.name = x
            obj.age = y
            obj.sex = z
    ​
        def run(self):
            print('----->', self)
    ​
    obj1=People('egon',18,'male') #People.__init__(obj1,'egon',18,'male')
    obj2=People('lxx',38,'female') #People.__init__(obj2,'lxx',38,'female')
    obj3=People('alex',38,'female') #People.__init__(obj3,'alex',38,'female')
    ​
    ​
    # __init__方法
    # 强调:
    #   1、该方法内可以有任意的python代码
    #   2、一定不能有返回值
    class People:
        country='China'
        x=1def __init__(obj, name, age, sex): #obj=obj1,x='egon',y=18,z='male'
            # if type(name) is not str:
            #     raise TypeError('名字必须是字符串类型')
            obj.name = name
            obj.age = age
            obj.sex = sex
    ​
    ​
        def run(self):
            print('----->', self)
    ​
    ​
    # obj1=People('egon',18,'male')
    obj1=People(3537,18,'male')
    ​
    # print(obj1.run)
    # obj1.run() #People.run(obj1)
    # print(People.run)
    ​
    !!!__init__方法之为对象定制自己独有的特征

     

    五、给对象绑定方法:

    1、绑定方法:

      绑定方法即将对象与函数方法绑定到一起(通过将对象本身传入函数来进行绑定),此后调用函数就变成了调用对象的方法。

      注:当用对象来调用类中的方法时,默认会将对象传入函数方法中,

        而用类名来调用时,则需要手动传入对象。

    #改写
    class OldboyStudent:
        school='oldboy'
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
        def learn(self):
            print('%s is learning' %self.name) #新增self.name
    def eat(self):
            print('%s is eating' %self.name)
    ​
        def sleep(self):
            print('%s is sleeping' %self.name)
    #注意:绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,self可以是任意名字,但是约定俗成地写出self。
    ​
    s1=OldboyStudent('李坦克','',18)
    s2=OldboyStudent('王大炮','',38)
    s3=OldboyStudent('牛榴弹','',78)
    ​
    s1.learn()
    OldboyStudent.learn(s1) #效果同上
    2、绑定方法分类:

      绑定方法有两种,一种是绑定给类的方法,一种是绑定给对象的方法。

      绑定给类的方法需要使用一个装饰器@classmethod,必须要有一个参数(类本身,默认为cls,可以自己定义,但是约定俗成的写成使用cls)。

    class Student:
        school = "beijing"def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    ​
        # 绑定方法分为两种 一种是绑定给对象的,一种绑定给类的
        # 绑定给类的方法 使用一个装饰器叫classmethod,必须有一个参数,表示当前类,参数名也可以自己定义,建议不要修改
        @classmethod
        def print_school(cls):  # 输出类里面叫school的属性
            print(cls.school)
    ​
        # def print_school2(self):  # 输出类里面叫school的属性
        #     print(self.school)
    # 这是绑定给对象的方法
        def sayHello(self):
            print(self.name, " 说: 你好")
    ​
    # Student.print_school_name()
    # Student.print_school()

      总结:两种绑定方法的使用场景:

        a、当要处理的的数据包含在类中时,就应该绑定给类;

        b、当要处理的数据包含在对象中时,就应该绑定给对象。

    3、非绑定方法:

      非绑定方法即在类中即不绑定给类,也不绑定给对象。

      特点:没有自动传参的效果,类和对象都能调用,就是一个隶属于类中的普通函数。

      应用场景:当这个功能不许要访问类中的数据,也不需要访问对象的数据时,就可以作为一个非绑定方法,应用场景较少。

    import json
     class Student:
         school = "oldboy"
         def __init__(self,name,gender,age,cla):
            self.name = name
            self.gender = gender
            self.age = age
            self.cla = cla
         def save(self):
             with open("%s.json"%self.name,"wt",encoding="utf-8") as f:
                 json.dump(self.__dict__,f)
         #此处既可以使用非绑定方法也可以使用绑定给类的方法:
         @staticmethod    #非绑定方法
         def get_obj(name):
             with open("%s.json"%name,"rt",encoding="utf-8") as f:
                 dic = json.load(f)
                 stu = Student(dic["name"],dic["gender"],dic["age"],dic["cla"])
                 return stu
     # stu1 = Student("yuyu","male",18,"5")
     # stu1.save()
     stu1 = Student.get_obj("yuyu")
     print(stu1.gender)
     
  • 相关阅读:
    百度地图常用 获取中心点 缩放级别等
    sqlserver 临时表,多用户同时访问冲突吗?
    批量改ID 行形式
    C# post Json数据
    windows 激活venv问题
    spring 改变url
    conductor编译镜像
    springboot教程
    Microsoft Visual C++ Compiler for Python 2.7
    java 方法引用(method reference)
  • 原文地址:https://www.cnblogs.com/peng-zhao/p/10116052.html
Copyright © 2020-2023  润新知