• Python


    什么是对象和类

    https://www.cnblogs.com/poloyy/p/15178423.html

    什么是 Python 类、类对象、实例对象

    https://www.cnblogs.com/poloyy/p/15178456.html

    类变量、实例变量/类属性、实例属性

    前言

    只是叫法不一样

    实例属性 = 实例变量

    类属性 = 类变量

    个人认为叫属性更恰当

    类属性和实例属性区别

    • 类属性,所有实例对象共享该属性
    • 实例属性,属于某一个实例对象的属性,用于描述具体的对象

    从实际栗子了解类属性、实例属性

    有一个表格,四个常见的明星

    姓名年龄
    周润发 58
    成龙 55
    刘德华 53
    周星驰 54

    总结一下

    • 四个人归类为明星
    • 每个明星都有两个属性:姓名、年龄
    • 明星这个群体具有一个属性:明星数量,在这张表是 4
    • 姓名和年龄等属性是用来描述具体的一个对象
    • 明星的数量是用于描述明星这个类别

    使用面向对象编程思想来总结的话

    • 周润发、成龙、刘德华、周星驰都是实例对象
    • 他们都属于明星,明星是
    • 属于实例对象的属性有:姓名、年龄,所以也叫实例属性
    • 属于明星类的属性有:数量,所以也叫类属性

    类里面的三种类型变量

    • 在所有方法之外定义的变量,称为类属性/类变量
    • 在方法内部,通过 self.变量名 方式定义的变量,称为实例属性/实例变量
    • 在方法内部,通过 变量名=变量值 方式定义的变量,称为局部变量

    类属性

    类属性在类中的定义

    class 类名:
        类属性1 = 值
        类属性2 =def func(self): 
            ...        

    类属性、类方法注意点

    • 无论是类属性还是类方法,都无法像普通变量或者函数那样,在类的外部直接使用它们(类方法后面详解)
    • 可以将类看做一个独立的空间,类属性其实也是在类体中定义的变量,类方法是在类体中定义的函数
    • 需要通过类对象/实例对象来调用类属性 ClassName.classProperty (类方法后面详解)

    类属性的栗子

    # 类属性
    class PoloBlog:
        # 这就是在所有方法之外 下面定义了 2 个类变量
        name = "小菠萝测试笔记"
        blog = "https://www.cnblogs.com/poloyy/"
    
    # 通过类名调用类属性
    print(PoloBlog.name)
    print(PoloBlog.blog)
    
    
    # 输出结果
    小菠萝测试笔记
    https://www.cnblogs.com/poloyy/

    通过 Pycharm 的代码联想,可以看到 blog、name、__doc__ 三个类属性

      

    类属性的调用方式

    有两种

    • 直接通过类名调用
    • 也可以通过类的实例对象调用

    调用类属性的栗子

    # 调用类属性的两种方式
    class PoloBlog:
        # 这就是在所有方法之外 下面定义了 2 个类变量
        name = "小菠萝测试笔记"
        blog = "https://www.cnblogs.com/poloyy/"
    
    
    # 通过类名直接调用
    print(PoloBlog.name)
    print(PoloBlog.blog)
    
    # 修改类属性
    PoloBlog.name = "blogyuan"
    PoloBlog.blog = "https://www.cnblogs.com/"
    
    # 通过实例对象调用修改后的类属性
    poloBlog = PoloBlog()
    print(poloBlog.name)
    print(poloBlog.blog)
    
    
    # 输出结果
    小菠萝测试笔记
    https://www.cnblogs.com/poloyy/
    blogyuan
    https://www.cnblogs.com/

    通过类名修改类属性的值,会影响所有的实例化对象

    实例对象修改类属性

    # 修改类属性
    poloBlog.name = "小菠萝回来了"
    
    # 再看看类对象调用修改后的类属性
    print(PoloBlog.name)
    print(poloBlog.name)
    
    
    # 输出结果
    blogyuan
    小菠萝回来了
    • 会发现,类名.name 仍然返回之前的值,而 实例对象.name 会返回修改的值
    • 原因: 实例对象.name 本质上并不是修改类属性的值,而是在定义一个新的实例属性(下面详解)

    动态添加类属性

    PoloBlog.age = 24
    print(PoloBlog.age)
    print(poloBlog.age)
    
    
    # 输出结果
    24
    24
    • age 没有在类体中定义
    • 可以直接通过 类名.new_property_name 的方式定义一个新的类属性

    实例属性 

    • 属于具体对象的属性,用于描述具体的对象
    • 只能通过实例对象访问,无法通过类名访问

    实例属性的栗子

    class PoloBlog:
        def __init__(self):
            # 在方法内部,通过 self.name 的方式定义的变量就是实例变量
            self.name = "小菠萝测试笔记"
            self.add = "https://www.cnblogs.com/poloyy/"
    
        # 下面定义了一个 say 实例方法
        def say(self):
            self.age = 13
    
    # 实例化对象
    blog = PoloBlog()
    blog.say()
    
    print(blog.name, blog.add, blog.age)
    
    
    # 输出结果
    小菠萝测试笔记 https://www.cnblogs.com/poloyy/ 13
    • 重点:__init__ 会在实例化对象的时候自动调用,因此 blog 创建成功就有 name、add 两个实例属性
    • 调用 say() 方法之后才有第三个实例属性 age

    修改实例属性的栗子

    blog.name = "小菠萝"
    blog.add = "xiaopolo.com"
    blog.age = 24
    
    print(blog.name, blog.add, blog.age)
    
    
    # 输出结果
    小菠萝 xiaopolo.com 24

    动态添加实例属性 

    blog.phone = 13501489999
    print(blog.phone)
    
    
    # 输出结果
    13501489999

    上面也有说到,通过 实例对象.属性名 的方式并不会给类变量赋值,而是定义一个新的实例变量

    综合栗子

    # 综合栗子
    class PoloBlogObjectTest:
        # 类变量
        sum = 0
    
        # 初始化方法
        def __init__(self, name, age):
            # 实例变量
            self.name = name
            self.age = age
            # 类变量
            PoloBlogObjectTest.sum += 1
    
        # 实例方法
        def printNameAge(self):
            print(self.name, self.age)
    
    
    poloTest1 = PoloBlogObjectTest("小菠萝一号", 24)
    poloTest2 = PoloBlogObjectTest("小菠萝二号", 14)
    
    print(PoloBlogObjectTest.sum)
    # 调用实例方法
    poloTest1.printNameAge()
    poloTest2.printNameAge()
    
    
    # 输出结果
    2
    小菠萝一号 24
    小菠萝二号 14

    不推荐实例属性和类属性同名

    • 类中,实例属性和类属性可以同名
    • 但这种情况下使用实例对象将无法调用类变量,它会首选实例变量,无论这个变量是否已定义
    • 实例独享绑定新的实例属性时,会直接覆盖掉重名的类属性

    实例属性、类属性同名栗子

    class Person:
        # 只有一个类变量
        name = "cool guy"
    
    # 实例化一个对象
    p = Person()
    # 打印实例属性 name,因为实例对象并没有name属性,所以会继续查找class的name属性
    print(p.name)
    # 打印类属性 name
    print(Person.name)
    
    # 给实例绑定 name、age 属性
    p.name = "bad guy"
    p.age = 12
    
    # 打印 name、age 属性
    print(p.age)
    # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的 name 属性
    print(p.name)
    # 仍然打印类的 name 属性
    print(Person.name)
    
    
    # 输出结果
    cool guy
    cool guy
    12
    bad guy
    cool guy

    实例对象属性引用的查找过程

  • 相关阅读:
    楔入式侧链原理
    侧链带来的问题
    侧链的应用方向
    node.js 读取yaml文件
    用Visual Studio Code写Node.js
    Express中server和路由分离
    Nodejs开发框架Express4.x开发手记
    node.js express使用websocket
    Nodejs 发送HTTP POST请求实例
    rabbitMQ消息队列原理
  • 原文地址:https://www.cnblogs.com/poloyy/p/15178468.html
Copyright © 2020-2023  润新知