以下大部分均搬运自:Python's @classmethod and @staticmethod Explained
@classmethod & @staticmethod
class Student(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
@classmethod
def from_string(cls, name_str):
first_name, last_name = map(str, name_str.split(' '))
student = cls(first_name, last_name)
return student
if __name__ == "__main__":
scott = Student('Scott', 'Robinson')
scott1 = Student.from_string('Scott Robinson')
其中在@classmethod中cls是作为class methods的the first argument,就像是实例化方法__init__中的self作为instance methods的the first argument。(参考PEP 8)
和@staticmethod的一个优点是,不要实例化就可以调用(类)方法。但是@staticmethod是在不传cls进去的情况下调用,例如:
class Student(object):
@staticmethod
def is_full_name(name_str):
names = name_str.split(' ')
return len(names) > 1
Student.is_full_name('Scott Robinson') # True
Student.is_full_name('Scott') # False
相同点:都是decorator(A Python decorator is a specific change to the Python syntax that allows us to more conveniently alter functions and methods (and possibly classes in a future version). );These types of methods aren't typically meant to create/instantiate objects, but they may contain some type of logic pertaining to the class itself, like a helper or utility method.
主要区别:This cls
parameter is the class object we talked about, which allows @classmethod
methods to easily instantiate the class, regardless of any inheritance going on. The lack of this cls
parameter in @staticmethod
methods make them true static methods in the traditional sense.
讲到底是@classmethod是一种可以轻松完成实例化的方法,而@staticmethod是真正的“静态”方法。
文章最后还留个例子:
class ClassGrades:
def __init__(self, grades):
self.grades = grades
@classmethod
def from_csv(cls, grade_csv_str):
grades = map(int, grade_csv_str.split(', '))
cls.validate(grades)
return cls(grades)
@staticmethod
def validate(grades):
for g in grades:
if g < 0 or g > 100:
raise Exception()
try:
# Try out some valid grades
class_grades_valid = ClassGrades.from_csv('90, 80, 85, 94, 70')
print 'Got grades:', class_grades_valid.grades
# Should fail with invalid grades
class_grades_invalid = ClassGrades.from_csv('92, -15, 99, 101, 77, 65, 100')
print class_grades_invalid.grades
except:
print 'Invalid!'