• day23


    ## 复习

    4.类与对象的语法
    class 类名:
    代码块(一堆属性与方法)
    对象名 = 类名()


    变量 | 函数 => 属性 | 方法:前者直接使用,通过所属者.语法调用

    类会随所属文件加载而加载(执行内部所有代码),形成类的名称空间
    3.提前在类中属性的属性与方法,在对象一产生就可以使用这些属性和方法
    '''
    '''
    2.拥有名称空间的对象:有__dict__属性,该属性就是指向对象的名称空间
    -- 文件 | 包(__init__.py文件) | 函数 | 类
    -- 可以为__dict__属性添加值,简化为.语法,也可以对__dict__整体赋值一个字典
    '''
    dic = {'a': 1, 'b': lambda x, y: x + y}
    def fn():
    print('fn run')
    fn()
    fn.name = '函数'
    print(fn.name)
    print(fn.__dict__)
    fn.__dict__ = dic
    print(fn.__dict__)
    print(fn.a)
    print(fn.b(10, 20))

    class Student:
    def __init__(self, name, sex):
    print('2>>>', self)
    self.name = name
    self.sex = sex


    def fn():
    print('fn run')
    def set_stu(stu, name, sex):
    stu.name = name
    stu.sex = sex

    ## 对象独有的名称空间: 在产生对象时就赋初值


    class Student:
    def __init__(self, stu_name, sex):
    self.name = stu_name
    self.sex = sex # 通常建议参数名与新增的属性名同名

    stu = Student('Bob', 'male') # 实例化对象
    print(stu.name, stu.sex)


    # __init__方法会在实例化对象时被调用
    # 1.会为实例化的对象形成空的名称空间
    # 2.就是一个方法,可以被传参,在 类名(实参) 这种方式下调用并传参 __init__(self, 形参)
    # 3.第一个self就是要产生的当前对象
    # 重点:在方法内部,形参拿到了实参值,利用self.属性名 = 形参 = 实参值,对对象的名称空间添加属性


    #对象特有的名称空间


    # print(Student.__dict__)
    Student.fn()
    stu1 = Student()
    # print(stu1.__dict__) # set_stu并不存在stu1的名称空间,由类来调用
    Student.set_stu(stu1, 'Bob', 'male')
    print(stu1.__dict__)
    print(stu1.name)
    print(stu1.sex)

    stu2 = Student()
    Student.set_stu(stu2, 'Tom', 'female')
    print(stu2.name, stu2.sex)

    ```

    ## 类中方法的第一个默认参数:对象方法


    class A:
    # 对象方法
    def test(self, num):
    pass
    a = A()

    # 调用方法
    # 二级优化
    a.test(10)
    # 一级优化
    A.test(a, 10)
    # 实现原理
    A.__dict__['test'](a, 10)

    # 总结:对象a传递给self,数字10传递给num
    # 重点:方法的第一个参数一定是调用该方法的对象


    class Student:
    pass
    stu = Student()

    # def fn(a, b):
    # print('fn run')
    # stu.fn = fn
    # stu.fn(10, 20)

    def func(arg):
    print('func run')
    Student.func = func # 将这个函数加入到类中的话,必须要写一个参数arg,不管有没有用,固定的就是将对象传入func,不然会报错
    # Student.func()
    # stu.func() == Student.__dict__['func'](stu) == Student.func(stu)
    '''
    ```

    ## 类中@classmethod修饰的方法:类方法

    ```python
    class Tool:
    @classmethod
    def add(cls, n1, n2): # 统一类与对象都可以调用类方法,一定有默认传入第一个参数
    return n1 + n2

    # 建议
    Tool.add(10, 20) # 默认第一个传入自身 - Tool

    # 不建议
    tool = Tool()
    tool.add(100, 200) # 默认第一个传入自身所属类 - tool.__class__


    class Tool:
    def add(n1,n2):
    return n1+n2

    res=Tool.add(10,20) # 类调用自己的函数属性,就是function,函数需要传入几个参数,就需要传入几个参数,
    # 然后拿到返回值,如果是对象调用的话,就不需要,因为对象调函数就是bound method
    print(res)
    ```

    ## 属性与方法的总结

    ```python
    class Tool:
    # 类自己的方法
    def add(cls, n1, n2):
    cls.fn()
    return n1 + n2

    def fn():
    pass

    # a如果被外界对象tool调用,那么内部调用b,b其实也是被外界对象tool调用的
    def a(self):
    self.b()
    def b(self):
    pass

    res = Tool.add(Tool, 10, 20) # 类调用,外界传入两个参数,内部接收到两个
    print(res)


    class Tool:
    # 类方法:可以被类与对象调用的方法,第一个参数一定是类
    # 类方法不建议拿对象来调用
    @classmethod
    def add(cls, n1, n2):
    print(id(cls))
    cls.test()
    return n1 + n2

    @classmethod
    def test(cls):
    pass

    print(Tool.add(10, 20))
    tool = Tool()
    print(tool.add(100, 200))
    print(id(Tool), id(tool))

    # 对象调用所属类的类方法,默认第一个参数传入的是 对象.__class__ 就是所属类
    print(tool.__class__)

    class OldBoy:
    # 属于类的属性
    name = '老男孩'

    # 属于对象的属性
    def __init__(self, name):
    self.name = name

    # 属于类的方法
    # 需求:获取机构的名字
    @classmethod
    def get_class_name(cls):
    return cls.name

    # 属于对象的方法
    # 需求:获取校区的名字
    def get_school_name(self):
    return self.name

    # 先创建校区
    shanghai = OldBoy('上海校区')
    shenzhen = OldBoy('深圳校区')

    # 类方法的使用
    # 建议使用类调用
    print(OldBoy.get_class_name())
    # 类方法拿对象调用并没有多少新增的意义,不建议拿对象调用
    print(shanghai.get_class_name())
    print(shenzhen.get_class_name())

    # 对象方法的使用
    # 类调用对象方法,必须把要操作的对象手动传入,不建议使用
    print(OldBoy.get_school_name(shanghai))
    print(OldBoy.get_school_name(shenzhen))
    # 对象调用对象方法,默认将自身传入,建议使用
    print(shanghai.get_school_name())
    print(shenzhen.get_school_name())
    ```

    ### 封装

    #封装语法
    class A:
    # __开头的属性,在外界不能通过 cord | __cord 直接访问:对外隐藏了
    __cord = '01012300'

    # __开头的方法,在外界不能通过 get_money | __get_money 直接访问:对外隐藏了
    @classmethod
    def __get_money(cls):
    print('输入密码,取出100w零花钱')

    # 内部还是可以直接访问__开头的属性与方法
    @classmethod
    def test(cls, flag):
    print('test方法被外界调用')
    # 在调用test与访问具体数据与功能间添加安全处理的操作
    if flag == '自家人':
    print(cls.__cord)
    cls.__get_money()

    # print(A.__cord)
    # A.__get_money()
    A.test('自家人')


    # 封装的原理:把用__开头的名字更名为 _类名__变量名,所以直接通过 变量名 | __变量名就访问不到
    # print(A.__dict__)
    print(A._A__cord)
    A._A__get_money()

    ## 对象的属性方法封装与接口提供


    # 对象的属性与方法封装集中与类的属性与方法封装原理一样
    class AAA:
    def __init__(self, money):
    self.__money = money
    self.__id = 1000

    @property
    def id(self):
    return self.__id
    @id.setter
    def id(self, id):
    self.__id = id

    # 对象的属性封装
    # 1.对象的属性值一般都来源于外界,外界是有权力再次访问的
    # 2.封装的目的不是让外界无法访问,而且不让其直接访问,可以在完成安全处理后再访问
    # 3.如何做到外界还是通过变量名来对属性进行取值赋值,但是是走的方法间接拿到的值
    # -- __money被封装,外界还是可以通过 对象.money 取值赋值


    # 取值
    @property # 在外界可以 对象.money 进行取值
    def money(self):
    # print('走方法拿到的money')
    return self.__money

    # 赋值
    @money.setter # 在外界可以 对象.money = 新值 进行赋值
    def money(self, money):
    self.__money = money

    # 删除
    @money.deleter
    def money(self):
    # print('逗你玩')
    del self.__money

    def get_money(self, flag):
    if flag == '自家人':
    return self.__money
    return 0

    def set_money(self, money):
    self.__money += money

    # 对象的方法封装一般的实现需求都是,这些方法只在内部使用
    def __test(self):
    print('test run')

    a = AAA(88888)
    # print(a.__money) # 正常方法不能访问
    # print(a._AAA__money) # 通过实现的原理也可以正常访问,假装不知道
    # a._AAA__test()

    print(a.get_money('自家人'))
    a.set_money(100000)
    print(a.get_money('自家人'))

    print(a.money)
    a.money = 999999
    print(a.money)

    # del a.money
    # print(a.money)
    ```


    # 重点:
    # 1.类的属性如何定义,类的方法如何定义
    # 2.对象的属性如何定义,对象的方法如何定义
    # 3.什么时候定义类方法与对象方法
    # 4.封装的语法与原理
    # 5.封装的目的
    # 6.对象属性的封装对外提供操作接口的手段
    ```

    ## 主要的总结


    #类:对象是特征与技能的结合体,而类则是一系列对象相同的特征与技能的结合体
    # 类体代码会在类定义阶段立即执行,会产生一个类的名称空间,用来将类体代码执行过程中的名字都会丢进去。
    # 1类的本质就是一个名称空间,或者说是一个用来存放变量与函数的容器
    # 2类的用途之一就是当作名称空间从其内部取出名字来使用
    # 3类的用途之一是调用来产生对象
    '''
    #站在老男孩的角度
    #总结出现实世界中的老男孩学生对象
    学生对象1:
    特征:
    school=’odlboy'
    name='李铁蛋
    age=18
    sex='male'
    技能:
    选课

    学生对象2:
    特征:
    school=’odlboy'
    name='赵钢弹‘
    age=38
    sex='female'
    技能:
    选课


    学生对象3:
    特征:
    school=’odlboy'
    name='刘银弹‘
    age=28
    sex='male'
    技能:
    选课


    老师对象1:
    特征:
    school=’odlboy'
    name='刘银弹‘
    age=28
    sex='male'
    level=10
    技能:
    打分


    总结现实世界中的老男孩学生类:特征与技能相同结合体
    相同的特征:
    school=’lodboy‘
    相同的技能
    选课
    '''


    '''
    #在程序中:
    #1.先定义类
    '''
    class OldboyStudent:
    school='oldboy'
    def choose_course(self):
    print('choosing course')

    #查看类的名称空间 2.类与对象都可以通过.语法来拓展新功能
    print(OldboyStudent.school)
    print(OldboyStudent.__dict__)
    print(OldboyStudent.__dict__['school'])
    OldboyStudent.choose_course('qwe') #必须要传值,不管是什么,如果是类调用的话
    # OldboyStudent.choose_course() #报错

    #可以改变类内的值,也可以加值,调用类内的函数
    #改值
    OldboyStudent.school='OLDBOY'
    #加值
    OldboyStudent.country='China'
    print(OldboyStudent.__dict__['country'])
    #删值
    del OldboyStudent.country


    # 后调用类来产生对象,产生三个空的名称空间 1.每个实例化出来的对象及类都有自己的名称空间
    stu1=OldboyStudent()
    stu2=OldboyStudent()
    stu3=OldboyStudent()

    print(stu1.__dict__)
    print(stu2.__dict__)
    print(stu2.__dict__)

    #,然后要往里面丢自己的特征与技能(加值)
    stu1.name='李铁蛋'
    stu1.age=18
    stu1.sex='male'
    print(stu1.__dict__)

    stu2.name='赵钢蛋'
    stu2.age=38
    stu2.sex='male'
    print(stu2.__dict__)

    stu3.name='赵银蛋'
    stu3.age=28
    stu3.sex='female'
    print(stu2.__dict__)

    #为对象定制自己独有的特征

    def init(obj,name,age,sex):
    obj.name=name
    obj.age=age
    obj.sex=sex

    init(stu1,'李铁蛋',18,'male')
    init(stu2,'赵钢蛋',28,'female')
    init(stu2,'赵银蛋',38,'male')
    #缺点就是重复的调用init

    # 将init加入要类中,将init 改为__init__为自动调用,减少函数体代码
    class OldboyStudent:
    school='oldboy'
    def __init__(obj, name, age, sex):# 这个函数内不能有返回值,因为这样会跟类冲突,因为类返回的是对象,而__init__是在对象产生后才运行的
    obj.name = name # obj必须是一个内存地址,有名称空间
    obj.age = age #在方法内部,形参拿到了实参值,利用self.属性名 = 形参 = 实参值,对对象的名称空间添加属性
    obj.sex = sex
    def choose_course(self):
    print('choosing course')
    #调用类发生了
    #1、产生一个空的对象,然后返回
    #2、触发类中的__init__的执行,将对象连同调用类括号内指定的参数一同传入__init__

    # 在类中定义__init__的好处就是对象拥有自己独有的特征
    stu1=OldboyStudent('李铁蛋',18,'male')
    stu2=OldboyStudent('赵钢蛋',28,'female')
    stu3=OldboyStudent('赵银蛋',38,'male')

    print(stu1.__dict__)
    print(stu2.__dict__)
    print(stu3.__dict__)

    #二、属性的查找顺序:先从对象自己的名称空间找,没有则去所属的类中找,如类中没有就报错

    # 三、类中的定义的变量是所有对象共享的,对象可以来用,类也可以来用,类一旦改变自己的数据属性的值,所有的对象都能感知到,
    # 而如果是对象本身自己改变,对其他对象没有影响

    #四、绑定方法
    # 类中的变量是类的数据属性,类可以用,对象也可以用,大家都指向同一个内存地址,类变量一旦改变都跟着改变
    # 类中定义的函数时类的函数属性,类可以使用,但类来调用就是一个普通的函数而且绑定给对象用的
    #类来调用函数就是该传几个值就传几个值function
    # 绑定方法:指向类的函数,特殊之处就是,绑定给谁就应该由谁来调用就会将谁当作第一个参数传入(bound method)

  • 相关阅读:
    Java 线程池
    Java 内存模型
    img图片铺满父元素
    element-ui 表单复杂数据类型校验
    element-ui 栅格布局 一行五等分
    element-ui表单只验证单个字段
    记录
    js-字符串全局替换
    vue3-搭建项目-vue2-vu3使用上的变化
    小程序引入echarts
  • 原文地址:https://www.cnblogs.com/huangxuanya/p/10747439.html
Copyright © 2020-2023  润新知