码农行者 码农行者
首页
  • Python

    • 语言特性
    • Django相关
    • Tornado
    • Celery
  • Golang

    • golang学习笔记
    • 对比python学习go
    • 模块学习
  • JavaScript

    • Javascript
  • 数据结构预算法笔记
  • ATS
  • Mongodb
  • Git
云原生
运维
垃圾佬的快乐
  • 数据库
  • 机器学习
  • 杂谈
  • 面试
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

DeanWu

软件工程师
首页
  • Python

    • 语言特性
    • Django相关
    • Tornado
    • Celery
  • Golang

    • golang学习笔记
    • 对比python学习go
    • 模块学习
  • JavaScript

    • Javascript
  • 数据结构预算法笔记
  • ATS
  • Mongodb
  • Git
云原生
运维
垃圾佬的快乐
  • 数据库
  • 机器学习
  • 杂谈
  • 面试
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Python中的类属性和实例属性

    • 问题
      • 分析
        • 总结
          • 推荐阅读
          • 开发语言
          • Python
          • 语言特性
          DeanWu
          2019-11-06
          目录

          Python中的类属性和实例属性

          # 问题

          今天在项目中遇到了个奇怪的问题,实例的一个时间属性并没有根据时间变化而变化,分析之后恍然大悟,总结下分享给大家。大家先看一段代码:

          import datetime
          import time 
          
          
          class Person(object):
              NOW = datetime.datetime.now()
          
              def __init__(self):
                  self.now = self.NOW
          
              def dosomething():
                """
                使用self.now 处理了些逻辑
                """
          
          if __name__=='__main__':
              for i in range(10):
                  p = Person()
                  print(p.now)
                  time.sleep(1)
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20

          且不说代码的优劣,大家觉着最后的打印会是什么样的呢?按照逻辑分析,在for循环中实例化了Person类,而now属性是实例的属性,每次调用在循环中打印,输出的一定是当时循环执行到该次循环的时间,即10次循环打印出的时间是不一样的。然而结果是这样的:

          2019-11-06 11:27:28.695771
          2019-11-06 11:27:28.695771
          2019-11-06 11:27:28.695771
          2019-11-06 11:27:28.695771
          2019-11-06 11:27:28.695771
          2019-11-06 11:27:28.695771
          2019-11-06 11:27:28.695771
          2019-11-06 11:27:28.695771
          2019-11-06 11:27:28.695771
          2019-11-06 11:27:28.695771
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10

          # 分析

          这里边体现了类属性和实例属性的区别。NOW 属于类属性,now属于实例属性。我们知道类属性可以被类和实例调用,实例属性只能被实例调用。我们在日常的业务逻辑开发中,并不会特意的去区分类属性和实例属性,而是直接使用实例来调用所有的属性,几乎不会使用类来调用属性。上边的代码在__init__中将类属性赋值给了实例属性,调用实例属性now时,间接的调用了类属性NOW。而类属性,在类加载的时候就执行了,即获取了当时的时间。它并不会随着实例的调用而改变。

          # 总结

          这里总结下类属性和实例属性的区别:

          • 类属性可以被类和实例调用,实例属性只能被实例调用
          • 类属性不会随着实例的调用而改变
          • 类属性的有效作用域只有类,实例属性的有效作用域只有本实例(有效作用域并非官方描述,而是我做的一个类比,大家可与作用域类别)。

          其中第三句需要再解释下,当类属性被实例属性调用修改时,修改的只是实例作用域内的该属性值,并不会修改类的属性。大家可以看如下例子:

          class Persion(object):
              count = 0
          
              def __init__(self):
                  self.name = '人'
          
          
          if __name__ == '__main__':
              p = Persion()
              p.count += 1
          
              print(p.count)
              print(Persion.count)
          
          # output 
          1
          0
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17

          # 推荐阅读

          更多关于类属性和实例属性的资料,大家可阅读如下资料:

          • https://www.python-course.eu/python3_class_and_instance_attributes.php (opens new window)
          • https://www.geeksforgeeks.org/class-instance-attributes-python/ (opens new window)
          #Python
          上次更新: 2023/03/28, 16:27:19
          最近更新
          01
          chromebox/chromebook 刷bios步骤
          03-01
          02
          redis 集群介绍
          11-28
          03
          go语法题二
          10-09
          更多文章>
          Theme by Vdoing | Copyright © 2015-2024 DeanWu | 遵循CC 4.0 BY-SA版权协议
          • 跟随系统
          • 浅色模式
          • 深色模式
          • 阅读模式