python中奇特的类成员变量

在python里有类成员变量和对象成员变量,这有点像C++中的静态成员变量和成员变量的区别, 前者属于类,而后者属于对象。

最近用python写一个爬虫,涉及多线程,本来想使用类成员变量,作为各线程共享数据,结果发现一些诡异的现象。简单说来,就像下面的例子:

class A(object):
    mm = 100
    def __init__(self):
        print(id(self.mm))
        self.mm = self.mm + 1
        print(id(self.mm))

a = A()

a.mm
101

A.mm
100

发现self.mm = self.mm + 1中两个self.mm还不是一个变量。得写成:

class A(object):
    mm = 100
    def __init__(self):
        A.mm = A.mm + 1

如果变量是一个list或者dict,原来那样写就没问题,但是也需要留意一下写法:

class A(object):
    mm = []
    def __init__(self):
        self.mm.append('123')

写成这样也OK:

self.mm += ['123']

写成这样就不OK了,就是创建一个对象成员变量了:

self.mm = self.mm + ['123']

似乎如果是赋值,就会创建一个同名字的对象成员,而self.mm这种写法,在查找时会先找对象成员,再找类成员。

python的文档里,关于类的成员变量,有很好的描述:

Programmer’s note: Variables defined in the class definition are class variables; they are shared by all instances. To create instance variables, they can be set in a method with self.name = value. Both class and instance variables are accessible through the notation “self.name”, and an instance variable hides a class variable with the same name when accessed in this way. Class variables can be used as defaults for instance variables, but using mutable values there can lead to unexpected results. For new-style classes, descriptors can be used to create instance variables with different implementation details.

这段话表达了如下一些要点:

  1. 类成员变量为所有对象所共享,实际只是为对象的成员变量提供默认值,所以不要对它期望太高。
  2. 只要出现赋值,即self.name = value,都是创建一个新的对象成员变量,哪怕名字跟类成员一样。
  3. 类成员变量最好初始化为一些常量。
发表于 2014年10月29日 01:12   评论:0   阅读:2920  



回到顶部

首页 | 关于我 | 关于本站 | 站内留言 | rss
python logo   django logo   tornado logo