42

私はJavaのバックグラウンドを持っており、Pythonは初めてです。ファイルの読み取りと書き込みに関連するアプリケーションに固有のヘルパー関数を共有するスクリプトがいくつかあります。読み取りに関連する機能もあれば、書き込みに関連する機能もあります。正しいアプローチを探しているときに、これを見ました: Pythonの静的メソッド?

彼は答えの中で次のように述べています。

最後に、staticmethod は慎重に使用してください。Python で static-methods が必要になる状況はほとんどありません。別の「トップレベル」関数の方が明確な場合に、static-methods が何度も使用されているのを見てきました。

私はトップレベルの関数をよく理解していません。この単純な例を考えると、どちらが優れているかわかりません: 1) 静的リーダー関数を使用してリーダー用のクラスを作成し、ライター用に同じクラスを作成するか、2) これらのヘルパーを宣言します。グローバル関数として、なぜですか?

編集:このテーマに関する本当に良い記事を見つけましたhttp://tomayko.com/writings/the-static-method-thing

4

5 に答える 5

52

Java では、状態を共有しない静的関数をグループ化するだけでも、あらゆる場所でクラスを使用する (したがって、そのようなクラスは決してインスタンス化されない) という (私見では間違った) 考えがあります。

ここで Python は違います。共有状態1を持たない関数(したがって、Java では通常はstatic関数) があり、「実際の」クラス (= 実際にインスタンス化されたクラス) と密接に関連していない場合は、内部でフリー関数を使用するだけです。モジュール。

この背後にある理由は、クラスは実際にインスタンス化したい場合にのみ必要になるため、インスタンス固有の状態を共有する必要のないいくつかの関数のコンテナーとしてクラスを使用することは役に立たないということです。

実際には、モジュールをクラスと考えることができます。staticつまり、関数 (= static メソッド)、モジュール変数 (= static フィールド)、および型のコンテナです。

Python ではトップレベルの関数/オブジェクト/... がまだモジュール スコープであるため、トップレベルの関数を使用してもグローバルな名前空間汚染の問題が発生しないのは Python の優れた点です。したがって、不要なclass-tax を使用せずに、関数をモジュールごとにグループ化することができます。


  1. 実際には、モジュールレベルの変数 (つまり、シングルトン) の形式で、いくつかの共有状態を持つことができます。繰り返しになりますが、類推モジュール - 静的クラスが成り立つようです。
于 2013-08-15T22:04:00.560 に答える
14

Zen of Python ( import this) から:

Namespaces are one honking great idea -- let's do more of those!

Java のような言語で静的メソッドを作成する主な理由の 1 つは、これらのメソッドが最終的にグローバル名前空間を汚染しないようにすることです。(Java では、「パッケージ レベル」の関数を完全に禁止することで、独自の名前空間規則を強制していますが!) Python では、すべての「トップレベル」の関数は、それらの関数を含むモジュールの名前空間内に自動的に配置されるため、グローバルを汚染する危険はありません。このように名前空間。

つまり、他の多くの言語と同様に、Python はいくつかの異なる方法で名前空間を作成できます。この場合、モジュールが同じ名前空間の目的を果たし、クラスの定義に関連する煩雑さ (または認知的負荷) がなくても、静的メソッドのみを含むクラスを作成する必要はほとんどありません。

于 2013-08-15T22:11:20.093 に答える
5

関数がクラスに関連している場合は、静的メソッドにします。例えば:

class DBobject():
    name = StringProperty()

    @staticmethod
    def get_by_name(name):
        return db.select('select * from DBobject where name = "%s"' % name)

python = DBobject.get_by_name('python')

つまり、メソッドは DBobject クラスに完全に関連しているため、静的メソッドである必要があります。

于 2013-08-15T22:08:49.767 に答える
1

Python の静的メソッドのもう 1 つの側面は、インスタンスで呼び出された場合、self.

例えば:

class BaseClass:
    @staticmethod
    def my_method():
        return 0


class SubclassLeft:
    @staticmethod
    def my_method():
        return "left"


class SubclassRight:
    @staticmethod
    def my_method():
        return "right"


instances = [BaseClass(), SubclassLeft(), SubclassRight()]

for i in instances:
    print(i.my_method())

これを実行すると、

$ python example.py
0
left
right
于 2018-07-09T18:14:21.557 に答える