python中类变量与成员变量的使用注意点总结

yipeiwu_com5年前Python基础

前言

最近在用python写一个项目,发现一个很恶心的bug,就是同由一个类生成的两个实例之间的数据竟然会相互影响,这让我非常不解。后来联想到java的类有类变量也有实例变量,因此翻阅了相关资料,发现python也有类似的类变量和实例变量,下面来看看详细的介绍。

看下面的示例代码:

class A:
 x = 0
 def __init__(self):
 self.y = 0

x就是类变量,y就是实例变量。

原则上是没有错的,但是实际用的时候就发现一些恶心的问题(也就是我找了三天的bug)。。。比如下面的代码:

class A:
 x = []
 y = 0
 def __init__(self):
 pass
 def add(self):
 self.x.append('1')
 self.y+=1
a=A() 
print a.x,a.y
print A.x,A.y
a.add()
print a.x,a.y
print A.x,A.y
b=A() 
print b.x,b.y
print A.x,A.y

这里很明显x和y都是类变量,add的作用是分别对x和y做出修改。然后构造一个实例a,对实例a的值进行修改,最后构造实例b。

本以为这个结果是显而易见的,然而他输出的结果却是:

[] 0
[] 0
['1'] 1
['1'] 0
['1'] 0
['1'] 0

问题在哪?明明x和y都是类变量,在第二组print中为什么a.x和b.x一样,但是a.y和b.y就是不一样呢?

想了半天悟了一个道理。。。就是对于python来说,类变量的确是所有类共有的东西。但是那是在我们用的同一个引用的情况下,比如对于[]对象的append方法就是公用一个类变量了;但是对于赋值语句来说,如果在类中对类变量使用了赋值语句,那么python就会生成一个该对象的副本,以后的操作都是基于这个副本而不会对原来的类对象造成影响。这样就解释的通上面的现象了。

那么为了杜绝自己忘记类变量和实例变量的区别导致本不想公用变量的时候公用了变量,最好的办法就是在每个类中使用变量的时候重新初始化一下,这样就不会导致意外了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对【听图阁-专注于Python设计】的支持。

相关文章

Python中的并发编程实例

一、简介   我们将一个正在运行的程序称为进程。每个进程都有它自己的系统状态,包含内存状态、打开文件列表、追踪指令执行情况的程序指针以及一个保存局部变量的调用栈。通常情况下,一个进程依照...

python中安装模块包版本冲突问题的解决

问题 最近在工作中遇到一个问题,在安装python软件包的时候,经常会遇类似这样一个问题。比如对于ipython,机子本身安装的版本是1.2.1,显然太低,不足以跑jupyter,尝试...

详解python:time模块用法

详解python:time模块用法

time模块下有两种时间表示方法: 第1种是:时间戳的方式。是基于1970年1月1日0时0分0秒的偏移。浮点数。 第2种是:struct_time()类型的表示方法。gmtime()和l...

Django模板变量如何传递给外部js调用的方法小结

前言 因为工作的需要,最近一直在思考如何更好的组织Django中的静态资源,比如JS、CSS一类,如何结合前端构建工具写出更好的代码以及结构呢?下面这篇文章就给大家详细介绍了实现的方法,...

pandas DataFrame的修改方法(值、列、索引)

对于DataFrame的修改操作其实有很多,不单单是某个部分的值的修改,还有一些索引的修改、列名的修改,类型修改等等。我们仅选取部分进行介绍。 一、值的修改 DataFrame的修改方法...