下面列出了一个类属性定义的实例。
'''
Created on Mar 20, 2015
@author: jliu
'''
class Book(object):
'''Book class'''
#record the boot count
book_count = 0 #comment 1
def __init__(self, name, auther):
self.name = name
self.auther = auther
self.increase_count() #comment 2
# self.__class__.book_count += 1 #comment 3
@classmethod
def get_count(cls): #comment 4
return cls.book_count
@classmethod
def increase_count(cls):
cls.book_count += 1
if __name__ == '__main__':
print "book_count: %d" % Book.book_count #comment 5
booka = Book("Learning Python", "Bob Liu")
bookb = Book("Learning C++", "Bob Liu")
print "book_count: %d" % booka.book_count #comment 6
print "book_count: %d" % Book.get_count() #comment 7
程序运行结果如下:
book_count: 0
book_count: 2
book_count: 2
注解1:我们在Book类中定义了类属性boot_count,它为所有类共有,且在任何实例创建前就已经有效了。在Java中,静态变量(对应Python中的类属性)和实例变量(对应Python中的数据属性)两者定义可紧跟在类定义之后(前者需要static关键字修饰,后一个没有)。在Python中,只有类的属性可以在这里定义,数据属性需要在__init__方法中定义,且数据属性的应用,需要使用self界定符,而类的引用,使用cls界定符。
注解2、4:我们可以通过定义类方法,来有效获取和设置类的属性,需要注意的是,类方法传递的首参数是cls;而实例方法传递的首参数是self
注解3:__class__是每个类实例的一个内置属性(每个类都有此属性,可通过内置函数dir查看类的内置属性);它是类的一个引用,而self是类的一个实例。创建一个实例类时,会调用__init__方法,它会操作类的属性book_count。这里我们展示了两种操作方式,这些操作不止影响新创建的实例,也影响类本身。
注解5、6: 从例子中,我们看到,类属性既可以通过直接对类引用,也可以通过任意类的实例来使用。类属性在创建任何实例之前,就已经存在了。
注解6、7:从运行结果上看,通过实例获取的类属性值与类方法获取值一致