My Note / Zeliang YAO
  • Zeliang's Note
  • Dremio
    • Custom Class
  • 💕Python
    • Design Pattern
      • Creational
        • Abstract Factory
        • Factory Method
        • Singleton
        • Builder / Director
      • Structural
        • Adapter
    • Boto3
    • Typing
    • String
    • Requests
    • Iterator & Iterable
      • Consuming iterator manually
      • Lazy Iterable
    • Genrators
    • itertools
    • Collections
    • Customization
      • Customize built-in
      • Logging
      • Hdf5
      • Sqlite3 & Df
    • Pandas
      • Basic
      • Data cleaning
      • Merge, Join, Concat
      • Useful tricks
      • Simple model
      • Pandas acceleration
    • Pandas time series
      • Date Range
      • Datetime Index
      • Holidays
      • Function_to_date_time
      • Period
      • Time zone
    • *args and**kwargs
    • Context Manager
    • Lambda
    • SHA
    • Multithreading
      • Threading
      • Speed Up
    • Email
    • Improvement
    • Useful functions
    • Python OOP
      • Basic
      • @static / @class method
      • attrs module
      • Dataclasses
      • Dataclasses example
      • Others
    • Design patterns
      • Creational Patterns
      • Structural Patterns
      • Behavioral Patterns
  • 🐣Git/Github
    • Commands
  • K8s
    • Useful commands
  • Linux
    • Chmod
Powered by GitBook
On this page
  • Overview
  • @classmethod
  • @staticmethod

Was this helpful?

  1. Python
  2. Python OOP

@static / @class method

Overview

首先回顾一下Python OOP常见的三种方法:

  • instance method 实例/接口方法

  • class method 类方法

  • static method 静态方法

class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'

我们最常用的其实就是普通的接口方法,其他两个需要用类似装饰器的写法来标注。

类方法接受一个cls作为参数,它是指向MyClass本身的,并不是MyClass所创建的实例。

静态方法不接受self或者cls作为参数,所以不会修改类本身或者实例

@classmethod

看一下如何使用类方法,新建一个Pizza类,主要参数为原料ingredients

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

    def __repr__(self):
        return f'Pizza({self.ingredients })'
        
Pizza(['cheese', 'tomatoes'])
Out: Pizza(['cheese', 'tomatoes'])

现在问题来了,既然是Pizza类,会有不同口味的Pizza,他们的配方都是固定的,那么如何便捷的生成不同口味的Pizza呢,答案就是classmethod

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

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

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

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

类方法可以根据需求事先预定义生成的实例,减少了代码量,这里我们根据margherita和prosciutto两种口味pizza的原料提前准备好了,cls就是代表类本身,这样如果我们再生成一些实例时,会方便很多:

#生成一个margherita口味的pizza
m = Pizza.margherita()
Out:Pizza(['mozzarella', 'tomatoes'])

#生成一个prosciutto口味的pizza
p = Pizza.prosciutto()
Out:Pizza(['mozzarella', 'tomatoes', 'ham'])

@staticmethod

import math

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

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

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

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

这种情况下使用一个静态方法是一个好的选择,通过area这个普通的接口方法,可以调用circle_area来计算面积,封装性更好:

p = Pizza(4, ['mozzarella', 'tomatoes'])
p.area() 

Out: 50.26548245743669

PreviousBasicNextattrs module

Last updated 3 years ago

Was this helpful?

💕