# @static / @class method

### Overview

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

* instance method 实例/接口方法
* class method 类方法
* static method 静态方法

```python
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

```python
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

```python
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就是代表类本身，这样如果我们再生成一些实例时，会方便很多：

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

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

### @staticmethod

```python
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来计算面积，封装性更好：

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

Out: 50.26548245743669
```

<br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zeliang-yao.gitbook.io/my-note-zeliang-yao/useful/python-oop/static-class-method.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
