Python 中有很多方法:实例方法(instance method),类方法(class method)与静态方法(static method)。本文从语法及用途上做一些简单对比。
语法区别
class HornHub:
paied_users = 100
def __init__(self):
pass
def display(self, vid:str):
print(vid)
@classmethod
def get_revenue(cls):
return cls.paied_users * 10
@staticmethod
def print_something(msg:str):
pass
实例方法
实例方法最少也要包含一个 self
参数(self
只是一个变量名,可以用其他名称命令),用于绑定调用此方法的实例对象(Python 会自动完成绑定)。实例方法通常会用类对象直接调用。例如:
obj = HornHub()
obj.display(123)
类方法
Python 类方法和实例方法相似,它最少也要包含一个参数,通常将其命名为 cls,Python 会自动将类本身绑定给 cls
参数(注意,绑定的不是类对象)。也就是说,我们在调用类方法时,无需显式为 cls
参数传参。
和实例方法最大的不同在于,类方法需要使用 @classmethod
装饰器进行装饰。如果没有这个装饰器,则解释器会将方法解释为实例方法。
类方法推荐使用类名直接调用,当然也可以使用实例对象来调用(不推荐)。
HornHub.get_revenue()
应用场景
- 获取和类相关的信息并且可以创建出类的对象。
class Book(object):
def __init__(self, title):
self.title = title
@classmethod
def create(cls, title):
book = cls(title=title)
return book
book1, book2 = Book("python"), Book.create("python and django")
print(book1.title, book2.title)
- 精简代码,比如调用类中静态方法。使用静态方法调用另一个静态方法需要写上类的名字,而类名一旦修改,则代码也需要改动。
class Foo(object):
X, Y = 1, 2
@staticmethod
def averag(*mixes):
return sum(mixes) / len(mixes)
@staticmethod
def static_method():
return Foo.averag(Foo.X, Foo.Y)
@classmethod
def class_method(cls):
return cls.averag(cls.X, cls.Y)
foo = Foo()
print(foo.static_method())
print(foo.class_method())
静态方法
静态方法本质上即是一个函数,和普通函数的区别在于,静态方法定义在类这个空间(类命名空间)中,而函数则定义在程序所在的空间(全局命名空间)中。
它的用途是:有时候我们需要定义一些跟类有关的方法,但在实现时并不需要引用类或者实例,例如,设置环境变量,修改另一个类的变量等。这个时候,我们可以使用静态方法。 静态方法采用装饰器 @staticmethod
来定义。
上例中的 print_something()
用于打印信息,不需要调用类或者实例。对于静态方法,Python 并不需要传递类或者实例,因此,既可以使用类也可以使用实例来调用静态方法。
小结
-
实例方法
- 定义:第一个参数必须是实例对象,该参数名一般约定为
self
,通过它来传递实例的属性和方法(也可以传类的属性和方法)。 - 调用:只能由实例对象调用。
- 定义:第一个参数必须是实例对象,该参数名一般约定为
-
类方法
- 定义:使用装饰器
@classmethod
。第一个参数必须是当前类对象,该参数名一般约定为cls
,通过它来传递类的属性和方法(不能传实例的属性和方法)。 - 调用:实例对象和类对象都可以调用。
- 定义:使用装饰器
-
静态方法
- 定义:使用装饰器
@staticmethod
。参数随意,没有self
和cls
参数,但是方法体中不能使用类或实例的任何属性和方法。 - 调用:实例对象和类对象都可以调用。
- 定义:使用装饰器