用Python自定义的类,在运行中生成的对象,对象有成员变量。成员变量分为类变量(class variables)和实例变量(instance variables)。
有一种成员变量,class variables,有些书说这是类变量。关于类变量,简单一句话:类变量的值是所有此类对象共享的。下面分两种情况来看看类变量的运行时特征。
Class variables are shared in the sense that they are accessed by all objects (instances) of that class. There is only copy of the class variable and when any one object makes a change to a class variable, the change is reflected in all the other instances as well.
当python的类变量是不可变对象时:
class Employee:
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
这段代码能够的类有一个类变量,叫empCount,在每个对象初始化的时候,这个变量会加1,以此来表示对象的数量。下面是一些测试代码:
>>>
>>> e1 = test.Employee('e1','200')
>>> e1.empCount
1
>>> e2 = test.Employee('e2','200')
>>> e1.empCount
2
>>> e2.empCount
2
>>> e3 = test.Employee('e3','200')
>>> e2.empCount
3
>>> e3.empCount
3
>>>
生成了3个对象,这三个对象的empCount都是一样的。再看看下面这段测试代码:
>>>
>>> e1.empCount = 10
>>> e1.empCount
10
>>> e2.empCount
3
>>> e3.empCount
3
>>>
将e1.empCount改变,从Python的逻辑来分析,类变量是integer类型,是不可变类型,e1.empCount只是指向了一个另外的integer对象,因为e2,e3的这个成员变量的值没有变。
如果类变量是可变类型呢?看下面的代码:
class Dog:
tricks = [] # mistaken use of a class variable
def __init__(self, name):
self.name = name
def add_trick(self, trick):
self.tricks.append(trick)
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks # unexpectedly shared by all dogs
['roll over', 'play dead']
当类变量是可变类型时,就能看到真正的对象件的变量共享了。以上这段代码来自Python官方,包括注释。
还有一种类的成员变量,可以说成是实例变量,instance variables,不是共享的,比如Employee类的name和salary。记住:Python中的变量无需申明,赋值语句运行时就是新变量生成的时候。
Object variables are owned by each individual object/instance of the class. In this case, each object has its own copy of the field i.e. they are not shared and are not related in any way to the field by the samen name in a different instance of the same class. An example will make this easy to understand.
关于一般的实例变量,有一个有趣的细节,即可以在运行时动态增加实例变量。比如上面的Employee类,并没有定义gender这个变量,但是我们可以在运行时进行制定:
>>> e1.gender = 'male'
>>> e2.gender = 'female'
>>> e1.gender
'male'
>>> e2.gender
'female'
>>> e3.gender
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'Employee' object has no attribute 'gender'
>>>
给e1和e2定义新的实例变量,但是e3就没有这个变量。
ricequant网站的代码,就是通过对象的实例变量,在各个函数之间传递信息。
虽然在Python中,大家都是对象,但是只有自定义的类生成的对象,才能这样自由的“挂接”实例变量,python提供的基本类型对象是不提供这样的操作的。
Python的dict字典类型也有这个直接“挂接”的特性,直接对一个不存在的key进行赋值操作:
>>>
>>> d = {}
>>> d['a']='111'
>>> d
{'a': '111'}
>>>
最后,Python有几个built-in的函数与本文内容有关:getattr()、setattr()以及hasattr()