小编Dov*_*val的帖子

模块函数vs staticmethod vs classmethod vs no decorators:哪个成语更pythonic?

我是一名Java开发人员,他开玩笑地玩弄Python.我最近偶然发现了这篇文章,其中提到了Java程序员在学习Python时常犯的错误.第一个引起了我的注意:

Java中的静态方法不能转换为Python类方法.哦,当然,它会产生或多或少相同的效果,但类方法的目标实际上是做一些在Java中通常甚至不可能的事情(比如继承非默认的构造函数).Java静态方法的惯用翻译通常是模块级函数,而不是类方法或静态方法.(静态最终字段应转换为模块级常量.)

这不是一个性能问题,但是一个必须使用Java-idiom代码的Python程序员会因为输入Foo.Foo.someMethod而感到非常烦恼,因为它应该只是Foo.someFunction.但请注意,调用classmethod涉及额外的内存分配,调用static方法或函数不会.

哦,所有那些Foo.Bar.Baz属性链也不是免费的.在Java中,编译器会查找那些带点名称的名称,因此在运行时,它们中有多少名称并不重要.在Python中,查找在运行时发生,因此每个点都很重要.(请记住,在Python中,"Flat优于嵌套",虽然它与"可读性计数"和"简单优于复杂"相关,而不是与性能有关.)

我发现这有点奇怪,因为staticmethod的文档说:

Python中的静态方法与Java或C++中的静态方法类似.另请参阅classmethod()以获取对创建备用类构造函数有用的变体.

更令人费解的是这段代码:

class A:
    def foo(x):
        print(x)
A.foo(5)
Run Code Online (Sandbox Code Playgroud)

在Python 2.7.3中按预期失败,但在3.2.3中工作正常(尽管你不能在A的实例上调用该方法,只能在类上调用.)

因此,有三种方法可以实现静态方法(如果使用classmethod计算,则有四种方法),每种方法都有细微差别,其中一种看似无法记录.这似乎与Python的口头禅是不一致的应该有一个 - 最好只有一个 - 明显的方式来做到这一点.哪个成语是最Pythonic?各自的优点和缺点是什么?

这是我到目前为止所理解的:

模块功能:

  • 避免Foo.Foo.f()问题
  • 污染模块的命名空间比替代方案更多
  • 没有继承

静态方法:

  • 保持类中与类相关的函数以及模块命名空间之外的函数.
  • 允许在类的实例上调用该函数.
  • 子类可以覆盖该方法.

类方法:

  • 与staticmethod相同,但也将类作为第一个参数传递.

常规方法(仅限Python 3):

  • 与staticmethod相同,但不能在类的实例上调用该方法.

我是否想过这个?这不是问题吗?请帮忙!

python static-methods

65
推荐指数
3
解决办法
2万
查看次数

标签 统计

python ×1

static-methods ×1