Skip to content

Instantly share code, notes, and snippets.

@nlpjoe
Created March 5, 2018 06:07
Show Gist options
  • Select an option

  • Save nlpjoe/b099a5b559ea288b6ed9a4232d6f85da to your computer and use it in GitHub Desktop.

Select an option

Save nlpjoe/b099a5b559ea288b6ed9a4232d6f85da to your computer and use it in GitHub Desktop.
如何在Python中使用static、class、abstract方法 #python

静态方法,不需要对象初始化

class Pizza(object):
    @staticmethod
    def mix_ingredients(x, y):
        return x + y
 
    def cook(self):
        return self.mix_ingredients(self.cheese, self.vegetables)

类方法,用途:

  • 工厂方法:用于创建类的实例,如果用 @staticmethod, 则需要在函数中硬编码Pizza类名,这会使此工厂方法无法被继承。
  • 调用静态类:也是防止硬编码,防止其无法被继承。
class Pizza(object):
    def __init__(self, radius, height):
        self.radius = radius
        self.height = height

    @staticmethod
    def compute_area(radius):
         return math.pi * (radius ** 2)

    @classmethod
    def compute_volume(cls, height, radius):
         return height * cls.compute_area(radius)

    def get_volume(self):
        return self.compute_volume(self.height, self.radius)

抽象方法

最简单的实现:

class Pizza(object):
    def get_radius(self):
        raise NotImplementedError

子类继承必须实现get_radius函数。 缺点:没实现此函数,需要到子类调用此函数时才能被发现错误

改进:

import abc
 
class BasePizza(object):
    __metaclass__  = abc.ABCMeta
 
    @abc.abstractmethod
    def get_radius(self):
         """Method that should do something."""

使用abc后,当你尝试初始化BasePizza或者任何子类的时候立马就会得到一个TypeError,而无需等到真正调用get_radius的时候才发现异常。

技巧:混合静态方法、类方法、抽象方法

记住,声明一个抽象的方法,不会固定方法的原型,这就意味着虽然你必须实现它,但是我可以用

  • 任何参数列表来实现
  • 静态方法实现
import abc
 
class BasePizza(object):
    __metaclass__  = abc.ABCMeta
 
    @abc.abstractmethod
    def get_ingredients(self):
         """Returns the ingredient list."""
 
class Calzone(BasePizza):
    def get_ingredients(self, with_egg=False): # 任何参数列表
        egg = Egg() if with_egg else None
        return self.ingredients + egg

class DietPizza(BasePizza): 
    @staticmethod  			
    def get_ingredients(): # 静态方法实现
        return None

从Python3开始(在Python2中不能如你期待的运行,见issue5867),在abstractmethod方法上面使用@staticmethod和@classmethod装饰器成为可能。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment