Python高级特性(四)——实例方法、类方法、静态方法

一、示例

下面是包含着这三种方法的示例代码,先对它们的使用有一个直观的了解:

class TestClass:
    # 实例方法
    def method(self):
        return "instance method called", self

    # 类方法
    @classmethod
    def class_method(cls):
        return "class method called", cls

    # 静态方法
    @staticmethod
    def static_method():
        return "static method called"

二、实例方法

TestClass类中的第一个方法就是实例方法,我们在编写代码时出现最多的就是此类方法。它需要一个参数self,表示通过TestClass实例化的对象,在这个方法中,可以通过self来访问该对象的其他属性或者方法,特别容易修改对象的状态。当然也可以通过self.__class__属性访问类本身,这意味着实例方法也可以改变类状态。

三、类方法

第二个方法TestClass.class_method使用了@classmethod装饰器,将其标记为类方法。类方法不接受self参数,它接受一个cls参数指向类,由于类方法只能访问cls参数,所以它不能修改对象实例的状态,但是它能修改应用于类所有实例的类状态。

四、静态方法

第三个方法为静态方法,TestClass.static_method使用了@staticmethod装饰器,将其标记为静态方法。这种方法不接受self或cls参数,但是可以接受任意的其他参数。它和类方法一样,可以直接通过类调用,不用实例化对象。
故静态方法不能改变类或者对象的状态,只是属于某个命名空间中的方法。

五、如何使用类方法

下面是一个Pizza类:

class Pizza:
    def __init__(self, ingredients):
        self.ingrediens = ingredients

    def __repr__(self):
        return f'Pizza({self.ingrediens!r})'

我们将这个类成为披萨类,然而在现实生活中,披萨分为很多种,它们有着不同的名字。为了让用户创建不同的披萨,我们添加两个类方法

@classmethod
    def margherita(cls):
        return cls(['mozzarella', 'tomatoes'])

@classmethod
	def prosciutto(cls):
	    return cls(['mozzarella', 'tomatoes', 'ham'])

在margherita和prosciutto两个工厂函数中使用了cls而不是使用类名Pizza,这是由于以后可能会修改类名,这样就不用修改所有工厂函数了。这些工厂函数能实例化不同的对象,带有margherita和prosciutto特性的对象,通过Pizza.margherita()Pizza.prosciutto()直接生成了Pizza对象:

Pizza(['mozzarella', 'tomatoes', 'ham'])
Pizza(['mozzarella', 'tomatoes'])

每一个类只能拥有一个__init__函数,而使用类方法可以添加额外的构造函数。

六、使用静态方法

我们在类中定义一个静态方法circle_area来计算披萨面积,并且构造函数新增一个参数为披萨半径

import math


class Pizza:
    def __init__(self, radius, ingredients):
        self.radius = radius
        self.ingrediens = ingredients

    def __repr__(self):
        return f'Pizza({self.radius, self.ingrediens!r})'

    @classmethod
    def margherita(cls):
        return cls(['mozzarella', 'tomatoes'])

    @classmethod
    def prosciutto(cls):
        return cls(['mozzarella', 'tomatoes', 'ham'])

    def area(self):
        return self.circle_area(self.radius)

    @staticmethod
    def circle_area(r):
        return r ** 2 * math.pi


pizza = Pizza(4, ['mozzarella', 'tomatoes'])
print(pizza.area())
print(Pizza.circle_area(4))

七、要点

  • 实例方法需要一个类实例,可以通过self访问实例
  • 类方法不需要类实例,不能访问实例(self),但是可以通过cls访问类本身
  • 静态方法不能访问cls或self,其作用和普通函数相同,但属于类的名称空间
  • 静态方法和类方法能在一定程度上展示和贯彻开发人员对类的设计意图,有助于代码维护

你可能感兴趣的:(Python高级特性)