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.yprint A.x,A.y

a.add()print a.x,a.yprint A.x,A.y

b=A() print b.x,b.yprint 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就会生成一个该对象的副本,以后的操作都是基于这个副本而不会对原来的类对象造成影响。这样就解释的通上面的现象了。

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

来源:Myths的个人博客

时间: 2024-12-13 00:48:09

Python类变量和成员变量使用中有哪些注意事项?的相关文章

python无私有成员变量

python解释器将__init__函数里的__z变量转成 _classname__z了,明白规则后外部依然可以通过实力对象来访问. In [1]: class aa: ...: def __init__(self): ...: self.x = 10 ...: self.y = 11 ...: self.__z = 12 ...: In [2]: a = aa() In [3]: print a.x 10 In [4]: print a.y 11 In [5]: print a.__z ---

类变量、成员变量、局部变量

Java的中共有三种变量,分别是类变量,成员变量和局部变量.他们分别存放在JVM的方法区,堆内存和栈内存中. / ** * @author win * / public class Variables { / ** *类变量 * / private static int a; / ** *成员变量 * / private int b; / ** *局部变量 * @param c * / public void test( int c){ int d; } } 原文地址:https://www.c

Python类变量与实例变量及成员函数修饰方式说明(与Java定义方式进行类比)

Python类中的变量有类变量和实例变量之分. 类变量:变量绑定在类上,同一个类之间的共享变量,类比于Java中的静态变量static 公有变量定义 Java 的定义方式 class Test{ public static class_variable = "123" } Python3 定义方式 class Test: class_variable = "123" 私有变量定义 Java 的定义方式 class Test{ private static class

Python类变量和实例变量区别

深入理解python类的实例变量和类变量 Python变量的本质:被赋值1 普通python变量(非类相关变量)很容易理解,在被赋值后即变量存在,可读可写2 Python类的变量(类变量和实例对象变量)以某种方式在某地方被赋值,即存在,可被读写2.1 Python类变量被赋值     (1)类的设计里,             class里def外,通过变量名能被赋值             def里通过类对象即类名字的点运算变量名可被赋值      (2)程序里             通过类

Python的类成员变量默认初始值的坑

问题发现:一个循环内,缺省值初始化同名变量,其中的list成员不是空,会延续之前同名变量的值. 示例代码: # Define class class Variant(): # use def __init__(self, price = 500, description = 'default description', values = ['', '', '']): self.price = price self.description = description self.values = v

Java类变量和成员变量初始化过程

一.类的初始化 对于类的初始化:类的初始化一般只初始化一次,类的初始化主要是初始化静态成员变量. 类的编译决定了类的初始化过程. 编译器生成的class文件主要对定义在源文件中的类进行了如下的更改: 1)       先按照静态成员变量的定义顺序在类内部声明成员变量. 2)       再按照原java类中对成员变量的初始化顺序进行初始化. 一个java类和编译后的class对应的转换如下: 源文件: public class Person{ public static String name=

Python 类变量与实例变量的区别和用途

假设有一个类Eg: class Eg: n = 'abcd' def __init__(self,name): self.name = name 两个实例a和b: a = Eg('a') b = Eg('b') 那么name就是实例变量,n就是类变量.在生成实例的过程中,类变量存储在类的内存位置中,而实例变量存储在实例内存位置中. 此时,打印两个实例的n值,实例会从类的内存位置去取值,所以值都为abcd: print(a.n , b.n) >>abcd abcd 当在a的实例中修改n的赋值时,

Python的类变量和成员变量

先说明几个相关的术语:attribute.function.method. attribute:类对象的数据成员.我们经常会在Python代码出错时遇到:"AttributeError: 'My_Class' object has no attribute 'memberxxx'" function:普通函数 method:类方法 示例代码:

python类变量和实例变量的区别

类变量:是为类服务的,类所有的实例都共享使用,在一个地方被改变,所有调用的地方变量值都改变.定义类时的写法为类名.变量名 实例变量:是在实例中生效的,每个实例变量的值都根据实例本身需求进行修改,不会影响其他实例,定义类时的写法为self.变量名 (1)定义一个类 class C: a = 0   #类变量 b = 0   #类变量 def __init__(self, flag): self.a = flag   #实例变量 C.a = 1         #类变量赋值 C.b = 1