@classmethod方法有一个强制的第一个参数,但这个参数不是类实例,它实际上是未实例化的类本身。因此,一个典型的类方法可能是这样的:
class Student(object):def __init__(self, first_name, last_name):self.first_name = first_nameself.last_name = last_namescott = Student('Scott', 'Robinson')
@classmethod是这样的
class Student(object):def __init__(self,first,last_name):self.firstname=firstself.last_name = last_name@classmethoddef from_string(cls, name_str):first_name, last_name = map(str, name_str.split(' '))student = cls(first_name, last_name)return studentscott = Student.from_string('Scott Robinson')
print(scott.firstname)
@staticmethod可以从未实例化的类对象调用它
class Student(object):@staticmethoddef is_full_name(name_str):names = name_str.split(' ')return len(names) > 1Student.is_full_name('Scott Robinson') # True
Student.is_full_name('Scott') # False
由于没有传递self对象,这意味着我们也不能访问任何实例数据,因此也不能在实例化的对象上调用此方法。这些类型的方法通常并不意味着要创建/实例化对象,但是它们可能包含一些与类本身相关的逻辑类型,比如helper或utility方法。
@classmethod与@staticmethod的区别
@classmethod必须有cls参数,@staticmethod不需要
这个cls参数是我们讨论过的类对象,它允许@classmethod方法轻松地实例化类,而不管正在进行什么继承。在@staticmethod方法中缺少这个cls参数,使得它们成为传统意义上的真正静态方法。它们的主要目的是包含与类相关的逻辑,但是该逻辑不需要任何特定的类实例数据。
demo
class ClassGrades:def __init__(self, grades):self.grades = grades@classmethoddef from_csv(cls, grade_csv_str):grades = map(int, grade_csv_str.split(', '))cls.validate(grades)return cls(grades)@staticmethoddef validate(grades):for g in grades:if g < 0 or g > 100:raise Exception()try:# Try out some valid gradesclass_grades_valid = ClassGrades.from_csv('90, 80, 85, 94, 70')print 'Got grades:', class_grades_valid.grades# Should fail with invalid gradesclass_grades_invalid = ClassGrades.from_csv('92, -15, 99, 101, 77, 65, 100')print class_grades_invalid.grades
except:print 'Invalid!'