Pythonクラスのメソッドを注文する良い方法は何ですか?


89

Pythonクラスのメソッドを並べ替えたいのですが、正しい順序がわかりません。

PyDevを使用してEclipseでメソッドを抽出すると、Eclipseは抽出されたメソッドを変更されたメソッドの上に配置します。ただし、これにより、下位レベルの詳細が上位レベルの詳細よりも優先されます。ボブおじさんによると、私のコードが新聞の見出しのように読めるように、反対のことをする必要があります。私がJavaをプログラムするとき、私は彼のアドバイスに従うだけです。

Pythonのベストプラクティスは何ですか?


8
ベストプラクティスはありません。最も理にかなっていることを実行します-上部にある重要なものは良い考えであり、一貫性は一般的に良いことです。PEP-8はこれについて言及していません、そしてそれが石に設定されたとしたら、それはそれがあるでしょう。
Gareth Latty 2012

4
そして、PEP8でさえ常に石になっているわけではありません。
Ignacio Vazquez-Abrams

1
私は通常、機能(取得、設定など)についてグループ
ごとに行います

クラス宣言はメソッド関数を定義するだけであり、メソッド関数を呼び出さないため、メソッド関数の順序は任意である可能性があることに注意することが重要です。これにより、クラスメソッドルーチンのソースコードは、リストの後半で定義されるメソッド関数を正常に使用できます。
DragonLord

回答:


67

他の人が指摘しているように、メソッドを注文する正しい方法はありません。たぶんPEPの提案が役立つでしょうが、とにかく。できるだけ客観的にあなたの質問にアプローチしようと思います。

  • 最初のインターフェース:パブリックメソッドとPythonマジック関数は、クラスのインターフェースを定義します。ほとんどの場合、あなたや他の開発者は、クラスを変更するのではなく、使用したいと考えています。したがって、彼らはそのクラスのインターフェースに興味を持つでしょう。ソースコードの最初に配置すると、気にしない実装の詳細をスクロールする必要がなくなります。

  • プロパティ、マジックメソッド、パブリックメソッド:これら3つの間で最適な順序を定義するのは困難です。これらはすべて、クラスのインターフェイスの一部です。@EthanFurmanが言うように、プロジェクト全体で1つのシステムに固執することが最も重要です。一般的に、人々__init__()はクラスで最高の最初の関数を期待しているので、私はすぐ下の他の魔法の方法をフォローアップします。

  • 読み方:基本的に、ストーリーを伝えるには、ボトムアップまたはトップダウンの2つの方法があります。高レベルの関数を最初に置くことにより、開発者は最初の数行を読むことでクラスの大まかな理解を得ることができます。そうしないと、クラスを理解するためにクラス全体を読む必要があり、ほとんどの開発者にはそのための時間がありません。経験則として、メソッドは、本体から呼び出されるすべてのメソッドよりも優先されます。

  • クラスメソッドと静的メソッド:通常、これは上記で説明した読み取り順序によって示されます。通常のメソッドはすべてのメソッドを何度も呼び出すことができるため、最初になります。クラスメソッドは、クラスメソッドと静的メソッドのみを呼び出すことができ、次に来ることができます。静的メソッドは、クラスの他のメソッドを呼び出して最後に来ることはできません。

お役に立てれば。ちなみに、これらのルールのほとんどはPython固有のものではありません。メソッドの順序を強制する言語を私は知りませんが、もしそうなら、それは非常に興味深いでしょう、そしてコメントしてください。


1
通常、言語は順序付けを強制しません。ただし、一部の言語には共通の規則があります。たとえば、C#StyleCopには厳密な順序付けルールがあります。Javaについては、stackoverflow.com
questions / 4668218

1
クラスメソッド:これらはコンストラクターとしてよく使用され、通常は__init__明示的に(と組み合わせて__new__)または暗黙的に(デフォルトのコンストラクターを介して)呼び出すため、__init__。と一緒に配置する理由になります。(私はそれらが以前に 配置されたのを見たことがありませんが__init__。)
oulenz19年

15

正しい順序はありません。システムを選び、それを使い続けます。私が使用するものは次のとおりです。

class SomeClass(object):
    def __magic_methods__(self):
        "magic methods first, usually in alphabetical order"
    def _private_method(self):
        "worker methods next, also in alpha order"
    def a_method(self):
        "then normal methods, also in alpha order"

2
staticmethods、クラス変数、および@propertyで装飾されたメソッドの好みは何ですか?
ジョンミー2012

@JohnMee:私が何よりも優先するクラス変数。私は、メソッドの皮折りたたみ@staticmethod@classmethod@property、およびその他の@decorator私は、それは(プロパティの間に行く傾向にあることを除いて、どこに行くかを決定するための方法の種類を使用して行を_private_methodsしてnormal_methods)。
イーサンファーマン2012

したがって、順序が基本的に非常にプライベートな「魔法の」メソッドからプライベートから通常のメソッドに変わる場合、それは@classmethodsが次に来る(@classmethod def a_class_method(cls))、次に@staticmethods(@staticmethod def a_static_method())を意味するのでしょうか。少なくともそれは私が理解しているポリシーです... (私はそれが好きではないのでIDEが何も折りたたむことなく)
Kawu 2014

2

私はDjangoのソースで見た@Ethanに似た何かをします。主な違いは、領域を区切るための大きな「############」ブロックコメントです。例えば、

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"

明らかに、これは小さなクラスにはあまり役に立ちません。


19
しかし、私はそれらが魔法、公的または私的であることがわかります。私自身、そのようなコメントのブロックは積極的に嫌いです。それらすべてのリストを見たい場合は、折りたたまれたコードを見ることができます。機能関連のメソッドの特定のブロックの上にコメントを付けることは私がすることですが、このタイプのコメントの場合、メソッド名が教えてくれます。
クリスモーガン

繰り返しますが、私はこれをより大きなクラスに対してのみ行います。マジックメソッドをセミプライベート(メソッドや名前マングル(_)メソッドと混同するのは簡単だと思います。
Matt Luongo 2012

醜い####ブロックを意図的に配置することに気付いたとき、編集の途中で醜いブロックを削除していました。しかし、私はこの質問の内容である順序に同意します。####質問の範囲に関係がなく、例は小さなクラスであり、####とにかく使用しないため、この例からを削除することをお勧めします。:-)
Mateen Ulhaq 2018

1
@MateenUlhaqは、編集画面に表示される2番目と5番目のガイドライン「意味を変えずに明確にする」と「常に元の作者を尊重する」を参照してください。(これらは、編集者自身の意見に関係なく、無条件に適用されることを意図していることに注意してください。)この回答の全体的かつ唯一のポイントは、これらの醜いコメントブロックを表示することでした。それらがなければ、それはイーサンの答えとまったく同じことを言っており、それがここにある意味はありません。あなたはブロックが「故意に」そこにあったことを認めさえしました-これを知っているのに、なぜあなたはそれらを取りに行くのですか?
ハロー2018

1
@MIWright質問の範囲外だと思いました。ご覧のとおり、rev2には、Ethanとは異なる順序で、異なる順序(およびサブ順序!)で質問に答える資料がまだ含まれています。それにもかかわらず、ロールバックされました。
Mateen Ulhaq 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.