我是一名 Java 开发人员,经常玩弄 Python。我最近偶然发现了这篇文章,其中提到了 Java 程序员在使用 Python 时常犯的错误。第一个引起了我的注意:
Java 中的静态方法不会转换为 Python 类方法。哦,当然,它会产生或多或少相同的效果,但类方法的目标实际上是做一些在 Java 中通常甚至不可能的事情(比如继承非默认构造函数)。Java 静态方法的惯用翻译通常是模块级函数,而不是类方法或静态方法。(静态最终字段应转换为模块级常量。)
这并不是什么性能问题,但是对于必须使用此类 Java 惯用代码的 Python 程序员来说,当它应该只是 Foo.someFunction 时,键入 Foo.Foo.someMethod 会很恼火。但请注意,调用类方法涉及额外的内存分配,而调用静态方法或函数则不会。
哦,所有这些 Foo.Bar.Baz 属性链也不是免费的。在 Java 中,这些带点的名称由编译器查找,因此在运行时,您拥有多少实际上并不重要。在 Python 中,查找发生在运行时,因此每个点都很重要。(请记住,在 Python 中,“平面比嵌套更好”,尽管它与“可读性计数”和“简单胜于复杂”更相关,而不是与性能有关。)
我觉得这有点奇怪,因为staticmethod的文档说:
Python 中的静态方法类似于 Java 或 C++ 中的静态方法。另请参阅 classmethod() 以了解可用于创建替代类构造函数的变体。
更令人费解的是这段代码:
class A:
def foo(x):
print(x)
A.foo(5)
在 Python 2.7.3 中按预期失败,但在 3.2.3 中工作正常(尽管您不能在 A 的实例上调用该方法,只能在类上调用。)
所以有三种方法可以实现静态方法(如果你用 classmethod 算的话,有四种方法),每一种都有细微的差别,其中一种似乎没有记录。这似乎与 Python 的“应该有一种——最好只有一种——明显的方式”的口号不一致。哪个成语是最 Pythonic 的?各自的优缺点是什么?
到目前为止,这是我的理解:
模块功能:
- 避免 Foo.Foo.f() 问题
- 比替代品更污染模块的命名空间
- 无继承
静态方法:
- 将与类相关的函数保存在类内部和模块命名空间之外。
- 允许在类的实例上调用函数。
- 子类可以覆盖该方法。
上课方式:
- 与 staticmethod 相同,但也将类作为第一个参数传递。
常规方法(仅限 Python 3):
- 与 staticmethod 相同,但不能在类的实例上调用该方法。
这是我想太多了吗?这不是问题吗?请帮忙!