在 Python 类中对方法进行排序的好方法是什么?

我想对 Python 类中的方法进行排序,但我不知道正确的顺序是什么。

When I extract methods in 日食 with PyDev, Eclipse puts the extracted method on top of the modified method. But this puts the lower level details before the higher level details. According to 鲍勃叔叔, I should do the opposite, so that my code reads like the headlines of a newspaper. When I program in 爪哇咖啡 I just follow his advice.

What is the best practice for Python?

48105 次浏览

没有一个正确的顺序。选择一个系统并坚持它。我使用的是:

class SomeClass(object):


def __magic_methods__(self):
"magic methods first, usually in alphabetical order"


def _private_method(self):
"worker methods next, also in alphabetical order"


def a_method(self):
"then normal methods, also in alphabetical order"

我做了一些类似于 Django 源代码中看到的 伊森的操作,其中主要的区别是大的“ # # # # # # # # # #”块注释来划分区域。

比如说,

class SomeClass(object):


#################
# Magic Methods #
#################
def __magic_methods__(self):
"magic methods first"


##################
# Public Methods #
##################
def a_method(self):
"then normal methods, in order of importance"


###################
# Private Methods #
###################
def _private_method(self):
"then worker methods, grouped by importance or related function"

Obviously this is less useful for smaller classes.

正如其他人指出的那样,没有正确的方法来规划你的方法。也许 PEP 的建议会有用,但不管怎样。让我尽可能客观地回答你的问题。

  • 接口优先: 公共方法和 Python Magic 函数定义类的接口。大多数时候,您和其他开发人员希望使用类而不是更改它。因此,他们将对该类的接口感兴趣。将它放在源代码中首位可以避免滚动您不关心的实现细节。

  • 属性、 magic methods、公共方法: 很难在这三者之间定义最佳顺序,它们都是类接口的一部分。作为 Ethan Furman 说,在整个项目中坚持使用一个系统是最重要的。一般来说,人们希望 __init__()是类中最好的第一个函数,所以我继续使用下面的其他神奇方法。

  • 阅读顺序: 基本上,讲故事有两种方式: 自下而上或自上而下。通过将高级函数放在第一位,开发人员可以通过阅读前几行来粗略地理解类。否则,人们必须阅读整个类才能理解这个类,而大多数开发人员没有这个时间。根据经验法则,将方法置于从方法体调用的所有方法之上。

  • 类方法和静态方法: 通常,这是上面解释的 阅读次序所暗示的。普通方法可以调用所有方法,因此排在第一位。类方法只能调用类方法和静态方法,然后才能调用。静态方法不能调用类的其他方法,因此排在最后。

Most of these rules are not Python-specific by the way. I'm not aware of a language that enforces method order.

密码

class Bar(_Foo):
pass


class _Foo:
pass

引发异常,因为类 _Foo必须在使用之前定义。你也可以找到类似的函数引发异常的例子:

def bar(f=_foo):
pass


def _foo():
pass

考虑到这些示例,通常在公共类和函数之前定义私有类和函数是有意义的。这就是为什么保持一致性和定义 私人方法比公共方法先进是有意义的。