为什么在Python中根据@staticmethod选择模块级别的函数(根据Google样式指南)?

Han*_*aze -1 python static-methods

根据《 Google Python样式指南》,绝对不应(几乎)使用静态方法:

除非为了与现有库中定义的API集成而强制使用,否则切勿使用@staticmethod。改为编写模块级函数

该建议背后的原因是什么?

这仅适用于Google吗?还是在Python中使用静态方法还有其他(更一般的)缺点?

尤其是,如果我想在将由该类的其他公共成员函数调用的类内实现实用程序功能,则最佳实践是什么?

class Foo: 
    .......
    def member_func(self): 
        some_utility_function(self.member)
Run Code Online (Sandbox Code Playgroud)

Google Python样式指南

aba*_*ert 5

如何理解《 Google Python样式指南》中的内容:

除非为了与现有库中定义的API集成而强制使用,否则切勿使用@staticmethod。改为编写模块级函数

好吧,您应该将其理解为Google的风格指南。如果您要为Google编写Python代码,或者为符合该样式指南的项目做贡献,或者选择将其用于您自己的项目,答案很简单:@staticmethod除非被迫使用,否则不要使用API。

这意味着没有判断调用的情况:类内部的效用函数不会被@staticmethodAPI 强制为,因此不应为@staticmethod

出于其他一些常见的1原因,也是如此@staticmethod。如果您想要实例属性的默认值用来保存一个回调函数……太糟糕了,请寻找另一种写方法(例如,在inside中定义的局部函数__init__)。如果您想要看起来像a @classmethod但不显式地与子类共存的东西……太糟糕了,那么看起来就不能像a @classmethod


当然,如果您遵循Google的风格指南,那么您应该将其理解为只是众多观点中的一种。大量的Python开发人员并不@staticmethod像该指南那样难对付。当然,Google是许多Python代码的杰出开发者。另一方面,Google的风格指南是在编写时引入的Java-isms比今天更多的问题。2但是,您可能不想过多地考虑每个观点的分量。相反,当重要时,学习问题并提出您自己的意见。


至于您的特定示例,正如我在评论中所说:事实上,您自然会发现自己在写作some_utility_function(self.member)而不是直观地表示自己,self.some_utility_function(self.member)或者Foo.some_utility_function(self.member)您已经在直觉上将其视为函数,而不是@staticmethod。在这种情况下,您绝对应该将那个作为函数而不是编写@staticmethod

那可能只是互联网上一个人的意见,但是我认为大多数Python开发人员都会同意这种情况。有时候您自然而然地发现自己会self.在每次做出判断时都在每个呼叫之前加前缀。


1.好吧,并非完全常见。但是它们并不罕见,所以它们永远不会出现。而且它们很常见,以至于在讨论有关不赞成使用@staticmethodPython 3的讨论时,很快有人提出了这两种情况,并提供了标准库中的示例,这足以让Guido终止讨论。

2.在Java中,没有模块级函数,因此您不得不编写静态方法来模拟它们。几年来,大多数大学的CS程序都集中在Java上,并且大量的软件是用Java编写的,所以很多人在编写Python类时使用了太多@staticmethod的代码(以及getter和setter以及其他Java原理) )。


kin*_*all 2

您编写对 的调用的方式some_utility_function(),无论如何都没有在类上定义。如果是的话,您将使用self.some_utility_function()或可能Foo.some_utility_function()调用它。所以您已经按照样式指南推荐的方式完成了。

和装饰器主要用于告诉 Python 将什么作为第一个参数传递给方法来代替通常的:要么是类型,要么什么都不传递@classmethod。但是,如果您正在使用,并且既不需要实例也不需要其类型,那么它真的应该是该类的成员吗?这就是他们要求您在这里考虑的问题:当实用函数实际上没有以任何方式与该类绑定时,它们是否应该是类的方法?谷歌说不。@staticmethodself@staticmethod

但这只是谷歌的风格指南。他们决定希望程序员更喜欢模块级函数。他们的话不是法律。显然,Python 的设计者看到了它的用途,@staticmethod否则他们就不会实现它!如果您有理由将实用函数附加到类上,请随意使用它。