代码示例
首先给出代码事例,接下来的讨论都将基于这段代码:
class Person():
people = []
def __init__(self,name):
self.name = name
self.people.append(self.name)
# 普通的method
def work(self):
print('I\'m working')
@staticmethod
def book(n):
print('I have',n,'books')
@classmethod
def num_people(cls):
print('There are',len(cls.people),'people')
class variable
在上述代码中,class variable就是people
这个list,它是所有Person类及其对象都共享的一个变量,一个对象对people的修改,其他对象也是可见的。
tom = Person('Tom')
mary = Person('Mary')
mary.num_people()
上述代码的输出为There are 2 people。
同时,引用class variable(即people)不必使用Person类实例化出的对象,我们能够直接使用Person类来访问它:
print(Person.people)
输出为[‘Tom’, ‘Mary’]。
上述这个特性会为我们带来不少便利。
class method
了解了什么是class variable,我们接下来看看什么是class method。示例代码中的num_people()
就是class method。
首先,在语法上,我们要在class method前加上@classmethod
装饰器(decorator),同时,class method的参数不再是self,而是cls。
与class variable类似,class method也是Person类及其对象共有的。在class method中能够访问class variable,如people;同时我们可以直接通过Person类来调用num_people,即Person.num_people()
(当然,通过实例化出的对象来调用class method也是合法的,如前文的mary.numpeople()所示)。但是在class method中无法访问self.name等变量。
static method
在语法上,我们首先需要在static method前叫上@staticmethod
装饰器,来表明这是一个static method;其次,static method的参数没有self或者cls。
上述语法决定了static method与class method有很大的不同。static method不能使用任何变量/属性(如self.name),或者类变量/属性(cls.people),它就好像是一个“普通”的函数,只不过需要Person类或其对象来调用。
Person.book(3)
输出结果是I have 3 books。
那么static method有什么用呢?其中一个应用就是在模块化的编程方式下,我们可以构造一个模块,其中的类实现static method,当import这个模块时,我们无需实例化出对象,就能直接使用其中的method了。比如大家熟悉的math 模块,当import math
之后,我们可以直接使用math.sqrt()等函数了。