为什么在Python中不推荐使用staticmehtod

2023-07-08  本文已影响0人  东方胖

一、什么时候应该使用 staticmethod

staticmethod 是一个装饰器,它的作用是改变函数方法的性质,让我们可以忽略掉第一个 self 参数,并且使得可以同时使用类名和对象去调用它。

例如

class Foo:
    def f(self, x):
        return x * 5

f 的作用是将 x乘五倍。
在流行的 IDE 如果我们写下以上的代码,可能会收到一个提示


静态方法提示

Method may be static
哦,因为函数实现内部并没有特别的属于Foo 类对象的成员,所以IDE 提示我们应当把它改成静态方法,这表示表示方法不依赖这个类。

可以改成这样:

@staticmethod
    def f(x):
        return x * 5

外部可以这样用

Foo.f(10)

# or
foo = Foo()
foo.f(10)

如果跨越模块
很可能就是长成这样的代码

import foo # 假设模块名是 foo
foo.Foo.f()

下面我们要说——这样做不太好
首先我们看到使用上有一点点别扭——foo.Foo.f() 这违背我们使用内置库函数的经验——例如使用 sin cos 函数,我们是这样的

import math 
math.sin(10)
math.cos(1.0)

或者

from math import sin, cos
sin(10)
cos(1.0)

单就这个case而言这不是一个好主意 ——代码不太简洁。我们可以把 staticmethod 改成模块函数

什么时候应该用它?

很少的场景必须要用staticmethod

stackoverflow观点.png

事实上,静态函数的概念来自 C++ 以及Java,至少我们可以这样类比。
对于 Java 由于所有的代码 ,函数变量都放在一个 class 域内。
我们总有一些方法是不需要通过生成对象再去调用,因为一方面生成对象总是要回收,总是要调用构造函数,带来了一些不必要的开销,因此总是得想办法设计出一些函数,直接通过类名去调用的。当然 Java 的对象同样可以调它类内定义的静态函数。
而 C++ 略有区别,C++不允许通过对象的方式调用声明为static 的方法

回到 Python,Python与C++的一大区别就是,它每个文件都在诞生的时候都自动成为一个 module,具有作用域的效力,与C++中 #include<filename.h> 再联动编译不同,所以,可以认为, Python的一个模块文件本身有 class的域作用。
如果仅仅是为了封装的目的——即我们认为 f 函数是应该带个 Foo前缀,放在foo的范围内供其他工程师阅读,以示我们是明白 OO 编程,那么完全可以把这个方法写成模块级别的方法

一篇更激进的文章

这篇文章 原文链接 的观点更激进——他认为我们永远不要使用staticmethod

概括一下他的理由

Python之父 Guido van Rossum 原话摘录 -basically said as much in April, 2012

We all know how limited static methods are.(They’re basically an accident — back in the Python 2.2 days when I was inventing new-style classes and descriptors, I meant to implement class methods but at first I didn’t understand them and accidentally implemented static methods first. Then it was too late to remove them and only provide class methods.

大概意思就是说,静态方法在 2.2 出现就是一个意外,后来意识到了它很废但是删除已经来不及

代码规范

大多数有气候的代码规范不推荐 或减少使用staticmethod
例如谷歌开源项目代码规范
谷歌开源项目代码规范Python——函数与方法装饰器

这条tips:
仅在有显著优势时, 审慎地使用装饰器. 避免使用 staticmethod. 减少使用 classmethod.**

总结

参考链接

https://www.webucator.com/article/when-to-use-static-methods-in-python-never/
https://stackoverflow.com/questions/735975/static-methods-in-python
https://docs.python.org/zh-cn/3/library/functions.html?highlight=staticmethod#staticmethod

上一篇 下一篇

猜你喜欢

热点阅读