14

私はしばらく Python を使用してきましたが、メソッドを static として宣言するための構文が独特であることがわかりました。

通常のメソッドは次のように宣言されます。

def mymethod(self, params)
   ...
   return

静的メソッドが宣言されています。

def mystaticethod(params)
   ...
   return
mystaticmethod = staticmethod(mystaticmethod)

静的メソッド行を追加しない場合、コンパイラは自己欠落について不平を言います。

これは、他の言語ではキーワードと宣言文法を使用するだけの非常に単純なことを行うための非常に複雑な方法です。この構文の進化について誰か教えてもらえますか? これは単に既存の言語にクラスが追加されたからでしょうか?

クラスの後半に staticmethod 行を移動できるので、パーサーが簿記に非常に熱心に取り組んでいることも示唆しています。

後で追加されたデコレータ構文を認識していることに注意してください。元の構文が言語設計の観点からどのように生まれたかを知りたいです。私が考えることができる唯一の考えは、 staticmethod アプリケーションが関数オブジェクトを静的メソッドに変換する操作を呼び出すということです。

4

8 に答える 8

12

静的メソッドは、クラスが登場してからかなり後に Python に追加されました (クラスは非常に早い段階で、おそらく 1.0 よりも前に追加されました。静的メソッドは 2.0 くらいになるまで登場しませんでした)。それらは通常のメソッドの変更として実装されました。関数から静的メソッド オブジェクトを作成して静的メソッドを取得しますが、コンパイラはデフォルトでインスタンス メソッドを生成します。

Python の多くのことと同様に、静的メソッドが導入され、人々がそれらを使用してより良い構文を求めたときに洗練されました。最初のラウンドは、言語に新しい構文を追加せずにセマンティクスを導入する方法でした (Python は構文の変更に対して非常に耐性があります)。私は Guido ではないので、彼の頭の中で何が起こっていたのか正確にはわかりませんが、これはやや推測にすぎませんが、Python はゆっくりと動き、段階的に開発し、経験を積むにつれて物事を改良する傾向があります (特に、彼らは正しい方法を理解するまで何かを追加することを好みません.これが最初から静的メソッドのための特別な構文がなかった理由かもしれません.

ただし、mjv が示したように、「デコレータ」と呼ばれる 2.2 または 2.3 で追加された構文シュガーを介して、より簡単な方法があります。

@staticmethod
def mystaticmethod(params)
    ...
    return

構文は、メソッド定義の後@staticmethodに置くための砂糖です。mystaticmethod = staticmethod(mystaticmethod)

于 2009-09-25T14:24:47.687 に答える
11

voyagerとadurdinは、何が起こったのかを説明するのに良い仕事をしています。Python2.2に新しいスタイルのクラスと記述子が導入されたことで、新しく深いセマンティックの可能性が生まれました。そして、最も明らかに有用な例(静的メソッド、クラスメソッド)があります。 、プロパティ)は、新しい構文なしで組み込みの記述子タイプによってサポートされていました(デコレータの構文@fooは、新しい記述子が実際の有用性を十分に証明した後、数リリース後に追加されました)。私はGuido(必要なときにTim Petersがいる場所)をチャネルする資格はありませんが、私はその時点ですでにPythonコミッターであり、これらの開発に参加しました。それが実際に起こったことを確認できます。

これに関するボイジャーの観察は、Cを思い出させるものであり、目標どおりです。Pythonは、Cの構文を模倣したどの言語よりも多くの「Cの精神」をキャプチャすると長い間主張してきました(中括弧、if/whileの後の括弧、など)。「Cの精神」は、実際にはISO C標準の(非規範的な)理論的根拠の部分で説明されており、Pythonが4.5に一致すると私が主張する5つの原則(中かっこは必要ありません!-)で構成されています(いくつかのビデオがあります「PythonforProgrammers」に関する私のプレゼンテーションのウェブ。興味があればこれを取り上げます)。

特に、Spirit of Cの「操作を実行する方法を1つだけ提供する」は、Zen of Pythonの「1つ、できれば1つだけの明白な方法」と一致します。CとPythonは、私が信じています。は、均一性と非冗長性という理想的な設計を明示的に採用している2つの広く普及している言語です(これは理想的であり、100%に到達することはできません。たとえば、aとbが整数の場合、a+bとb+ aは、それらの合計を取得するための2つの同じように明白な方法であることがBETTERでした!-)-しかし、それは目指すべき目標です!-)。

于 2009-09-25T15:13:08.680 に答える
4

Python の静的メソッドは、Python 2.2 でのいわゆる「新しいスタイルのクラス」の導入にさかのぼります。これ以前は、クラスのメソッドは、クラスの属性として格納された単なる普通の関数でした:

class OldStyleClass:
    def method(self):
        print "'self' is just the first argument of this function"

instance = OldStyleClass()
OldStyleClass.method(instance) # Just an ordinary function call
print repr(OldStyleClass.method) # "unbound method..."

インスタンスのメソッド呼び出しは、インスタンスを関数の最初の引数に自動的にバインドするために特別に処理されました。

instance.method() # 'instance' is automatically passed in as the first parameter
print repr(instance.method) # "bound method..."

Python 2.2 では、クラス システムの多くが再考され、「新しいスタイルのクラス」、つまり を継承するクラスとして再設計されましたobject。新しいスタイルのクラスの機能の 1 つは「記述子」でした。これは基本的に、クラスの属性の記述、取得、および設定を担当するクラス内のオブジェクトです。記述子には__get__、クラスとインスタンスを渡すメソッドがあり、クラスまたはインスタンスの要求された属性を返す必要があります。

記述子により、単一の API を使用して、プロパティ、クラス メソッド、静的メソッドなどのクラス属性の複雑な動作を実装できるようになりました。たとえば、staticmethod記述子は次のように実装できます。

class staticmethod(object):
    """Create a static method from a function."""

    def __init__(self, func):
        self.func = func

    def __get__(self, instance, cls=None):
        return self.func

これを、classes 属性のすべての単純な関数に対してデフォルトで使用される、通常のメソッドの架空の pure-python 記述子と比較してください (これは、インスタンスからのメソッド検索で正確に起こることではありませんが、自動の「自己」を処理します)。口論):

class method(object):
    """Create a method from a function--it will get the instance
    passed in as its first argument."""

    def __init__(self, func):
        self.func = func

    def __get__(self, instance, cls=None):
        # Create a wrapper function that passes the instance as first argument
        # to the original function
        def boundmethod(*args, **kwargs):
            return self.func(self, *args, **kwargs)
        return boundmethod

したがって、 を記述するときmethod = staticmethod(method)は、実際には、元の関数を変更せずに返すことを仕事とする新しい記述子を作成し、この記述子をクラスの「メソッド」属性に格納しています。

元の機能を元に戻すだけでも大変な作業のように思われる場合は、その通りです。ただし、通常のメソッド呼び出しがデフォルトのケースであるため、静的メソッドとクラス メソッドは個別に実装する必要があり、記述子を使用すると、1 つの単純な API でこれらおよびその他の複雑な動作を有効にすることができます。

他の人がすでに指摘しているように、Python 2.4 で導入されたデコレーター構文は、静的メソッドを宣言するためのより便利な方法を提供しますが、これは単なる構文上の利便性であり、静的メソッドの動作方法を変更するものではありません。

新しいスタイルの詳細については、http: //www.python.org/doc/2.2.3/whatsnew/sect-rellinks.htmlおよびhttp://users.rcn.com/python/download/Descriptor.htmを参照してください。クラスと記述子。

于 2009-09-25T14:54:12.547 に答える
3

Guido は、言語に新しい構造を追加することに常に慎重でした。静的メソッドが提案されたとき、すでにそれを実行できることが示されました( staticmethod()2.2 以降のデコレーターがあります)。

PEP を読むと、何かを追加するためのすべての議論を見ることができます。私は、そのアプローチが好きです。C余計なキーワードがないのが気になります。

デコレーターの新しい構文が Python 2.4 に追加されたとき、既存のデコレーターをよりクリーンな構文で使用できます。

とにかく、古いシステムを維持しなければならない場合、それらはそれほど違いはありません。

#>2.4
class MyClass(object):
    @staticmethod
    def mystaticmethod(params)
        pass
        return

#<2.4
class MyClass(object):

    def mystaticmethod(params)
        '''Static Method'''
        pass
        return
    staticmethod(mystaticmethod)

静的メソッドである叫ぶ静的メソッドにコメントまたはドキュメント文字列を追加することをお勧めします。

于 2009-09-25T14:48:39.123 に答える
2

Pythonの静的メソッドの状況は、ファーストクラスのすべての設計上の決定の直接的な結果であり、すべてが実行可能ステートメントです。他の人が述べているように、staticmethodは、Python 2.2記述子プロトコルで許可された新しいセマンティクスでのみ利用可能になり、Python2.4の関数デコレーターによって構文的に甘くなりました。静的メソッドがあまり注目されていないのには単純な理由があります。静的メソッドは言語の能力を拡張せず、構文をわずかに改善するだけです。意味的には、それらは単純な古い関数と同等です。そのため、他の言語機能の観点から実装可能になるほど言語の能力が向上した場合にのみ、それらが実装されました。

于 2009-09-25T16:12:03.200 に答える
2

Python 2.4 以降では、次のようにデコレータを使用することもできます。

   @staticmethod
   def mystaticethod(params)
      ...
      return

しかし、言語で最初に実装されたこの機能の起源については、私は何の洞察も持っていません。しかし、繰り返しになりますが、私はオランダ人ではありません :-) Python の進化における静的メソッドの遅れた到着に関して、この投稿で Michael E の応答を参照してください。

ところで、すべての単純さのために、

@マイデコ
 someObject

   は単に「構文糖衣」です

  MyDeco(someObject)

デコレータは、他の多くのクールなことに使用できます。

于 2009-09-25T14:18:00.837 に答える
1

Guido はThe History of Pythonというブログを書いています。この特定のトピックについて詳しく知りたい場合は、彼に連絡する方法があると思います。

于 2009-09-25T14:31:29.993 に答える
0

おそらく、関数を使用できる場合に静的メソッドが必要であると当初は設計が考えていなかったのでしょう。Python にはデータを隠す機能がなかったため、クラスを名前空間として使用するよりも静的メソッドは必要ありません。

于 2009-09-25T14:24:51.533 に答える