我是一个Java开发人员,他喜欢开和关Python。我最近偶然发现了这篇文章,其中提到了Java程序员在选择Python时常犯的错误。第一个吸引了我的眼球:
Java中的静态方法不会转换为Python类方法。哦,可以肯定,它或多或少会产生相同的效果,但是类方法的目标实际上是要做通常在Java中甚至是不可能的事情(例如继承非默认构造函数)。Java静态方法的惯用翻译通常是模块级别的函数,而不是类方法或静态方法。(静态的final字段应转换为模块级常量。)
这并不是性能问题,但必须使用此类Java惯用语代码的Python程序员会因键入Foo.Foo.someMethod而应为Foo.someFunction而感到恼火。但请注意,调用类方法涉及额外的内存分配,而调用静态方法或函数则不会。
哦,所有那些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实例的方法)。
因此,有三种方法可以实现静态方法(如果使用类方法,则有四种方法),每种方法都有细微的差别,其中一种似乎没有记载。这似乎与Python的口头禅不一致,即应该有一种-最好只有一种-显而易见的方法。哪个成语是最Python化的?各自的优缺点是什么?
到目前为止,这是我的理解:
模块功能:
- 避免Foo.Foo.f()问题
- 污染模块的名称空间比其他方法更多
- 没有继承
静态方法:
- 将与类相关的函数保留在类内部,并保留在模块名称空间之外。
- 允许在类的实例上调用该函数。
- 子类可以覆盖该方法。
类方法:
- 与staticmethod相同,但也将类作为第一个参数传递。
常规方法(仅适用于Python 3):
- 与staticmethod相同,但不能在类的实例上调用该方法。
我在想这个吗?这不是问题吗?请帮忙!