0

メソッドの引数として関数を受け取るクラスを含むPythonのプログラムがあります__init__。この関数は属性として保存され、クラス内のさまざまな場所で使用されます。渡される関数は非常に多様である可能性があり、キーを渡してから事前定義された関数のセットから選択しても、同じ程度の柔軟性は得られません。

さて、このような質問の長いリストがクールではない場合はお詫びしますが...

  • 関数がファーストクラスのオブジェクトではない言語でこれを達成するための標準的な方法ですか?
  • smalltalkやobjective-Cのように、ブロックはこの点で関数としてカウントされますか?
  • これらの言語でこれを行うには、ブロックが最善の方法でしょうか?
  • ブロックがない場合はどうなりますか?
  • 実行時に新しいメソッドを追加できますか?
  • これはどの言語で可能(そして簡単)ですか?
  • または、目的の操作を実行する単一のメソッドを使用してオブジェクトを作成する方がよいでしょうか。
  • たくさんの関数を渡したい場合、たくさんのシングルトンオブジェクトを作成しますか?
  • これは、よりオブジェクト指向のアプローチと見なされますか?
  • 関数がファーストクラスのオブジェクトであるPythonでこれを行うことを誰かが検討しますか?
4

4 に答える 4

1

戦略パターンを使用できます。基本的に、既知のインターフェースを持つオブジェクトを渡しますが、動作は異なります。これは関数を渡すようなものですが、オブジェクトにラップされたものです。

于 2011-11-03T12:48:18.247 に答える
1

私はあなたの質問のいくつかに答えるつもりです。

彼らがSchemeコミュニティで言うように、「オブジェクトは貧乏人のクロージャです」(クロージャはファーストクラスの関数です)。ブロックは通常、クロージャーの単なる構文糖衣です。クロージャーを持たない言語には、さまざまな解決策があります。

一般的な解決策の 1 つは、演算子のオーバーロードを使用することです。C++ には、メンバーを定義する関数オブジェクトの概念がありますoperator()(「演算子関数呼び出し」)。Python には同様のオーバーロード メカニズムがあり、次のように定義します__call__

class Greeter(object):
    def __init__(self, who):
         self.who = who

    def __call__(self):
         print("Hello, %s!" % who)

hello = Greeter("world")
hello()

はい、関数はpickleできないため、オブジェクトに関数を格納する代わりに、Python でこれを使用することを検討してください。

演算子のオーバーロードのない言語では、Guava のFunctionインターフェイスのようなものが表示されます。

于 2011-11-03T12:30:39.577 に答える
1

「同等の... オブジェクト指向のアプローチを使用する」という意味がわかりません。Pythonでは、関数は(あなたが言うように)ファーストクラスのオブジェクトであるため、関数を引数として渡すのが「オブジェクト指向」ではないのはなぜですか?

関数がファーストクラスオブジェクトではない言語でこれを達成する標準的な方法は?

関数がファーストクラスのオブジェクトにならない標準的な方法があるという範囲でのみ、私は言います。

C++ では、 functorまたはfunctionoidと呼ばれることが多い別のクラスを作成するのが一般的です。これは、 のオーバーロードを定義し、operator()インスタンスを関数のように構文的に使用できるようにします。ただし、単純な古い関数ポインターでうまくいくこともよくあります。ポインターも指定された関数もファースト クラスのオブジェクトではありませんが、インターフェイスは十分に豊富です。

これは、テンプレートによって実現される「アドホック ポリモーフィズム」とうまく調和します。クラスのインスタンスを渡すか関数ポインタを渡すかを実際には気にしない関数を書くことができます。

同様に、Python では、クラスのメソッドをcallable定義することにより、オブジェクトを登録することができます。__call__

smalltalk や Objective-C のようなブロックは、この点で関数としてカウントされますか?

私は彼らがそうすると言います。ラムダは少なくとも Python の関数と同じくらい数えられます。実際には、Python のラムダのように機能しなくなっていないため、ラムダはそれ以上に数えられます。

ブロックはこれらの言語でこれを行うための最良の方法でしょうか?

必要なものによって異なります。

実行時に新しいメソッドを追加できますか? どの言語でこれが可能 (かつ簡単) でしょうか?

独自のコンパイラへのイントロスペクションとランタイム アクセスを提供する言語。Python が該当します。

ただし、これまでに提示されたように、問題については何もなく、そのようなフープを飛び越える必要があることを示唆しています。もちろん、一部の言語では、新しいクラスに対して他の言語よりも多くのボイラープレートが必要です。

それとも、目的の操作を実行する単一のメソッドでオブジェクトを作成する方がよいでしょうか?

それはかなり標準的です。

たくさんの関数を渡したい場合、たくさんのシングルトン オブジェクトを作成しますか?

これは、大量のボイラープレートを作成してそれを防ごうとしないと、クラスの複数のインスタンスを誤って作成する可能性があるかのように言います。

これは、よりオブジェクト指向のアプローチと見なされますか?

繰り返しますが、「オブジェクト指向」という用語に対するあなたの理解を理解することはできません。「たくさんのオブジェクトを作成する」という意味ではありません。

関数がファーストクラスオブジェクトであるPythonでこれを行うことを検討する人はいますか?

クラスにはできること、関数にはできないことを追加する必要がないわけではありません。アヒルのタイピングで、一体なぜあなたは気にするのですか?

于 2011-11-03T13:20:41.820 に答える