类属性 和 实例属性 php,Python 的类属性和实例属性引发的一个坑

8e5adf088197ece75efafbeed90e358c.png

问题

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

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)

且不说代码的优劣,大家觉着最后的打印会是什么样的呢?按照逻辑分析,在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

分析

这里边体现了类属性和实例属性的区别。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

推荐阅读

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

https://www.python-course.eu/python3_class_and_instance_attributes.php

https://www.geeksforgeeks.org/class-instance-attributes-python/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值