空の関数が必要な理由


9

私はpythonの学習を開始し、なぜプログラミング言語で空の関数が必要なのか疑問に思っています

例:python:

def empty_func():
    pass

シェルスクリプトでも、空の関数空の関数を使用できます。

私の理解と質問:

  1. なぜプログラミング言語は空の関数を必要としたのですか?それは、プログラミング言語で遊んでいるだけなのか、それとも本当に重要なことなのか?

  2. これに目的がある場合、誰かがユースケースを説明したり、空の関数の使用法の実際の例を挙げたりできますか?

  3. または、空の関数を許可するプログラミング言語の伝統はありますか?


編集(私があなたの回答を読んで得たもの):

  • スケッチアルゴリズムまたは抽象関数用
  • アクションなしでフォームを送信するために実行する必要があります
  • いくつかの必須操作のプレースホルダー

1
プログラムの実行がそれらを検出/使用することを期待している場合は、それらをSTUBSとして使用できますが、それらを介して何も変更する必要はありません。
G.Rassovsky、2015年

回答:


5

Bourneファミリのシェル言語では、:コマンドは何もしないため、通常、次の2つの状況で使用されます。

  • 何かが必須コマンドを期待するときのためのプレースホルダー、例えば

    while some_condtion
    do :
    done
    

    以来、do少なくとも一つのコマンドが必要です。

  • 引数を破棄するが、引数リスト内で副作用を実行する、例えば

    : ${myvar=foo}

おそらくシェルの専門家が知っている他のアプリケーションがあると思います:)

Python(および他の言語)では、あまり使用されません。実際には何もしたくない場合は、高次関数の引数として機能します。たとえば、フォームを送信する関数があり、送信が完了した後にその関数を非同期的に呼び出せるとします。

def submit(callback=empty_func):
    ...

このようにして、callbackが提供されない場合でも、送信は行われますが、それ以上のアクションは実行されません。Noneデフォルト値として使用していた場合はNone、コールバックがであるかどうかを明示的に確認して、コードを整理する必要があります。


1

これは、開発サイクルのどこに立っているかによって異なりますが、アルゴリズムをスケッチするときに、複雑なブロックをすぐに実装せずに抽象化したい場合があります。

def full_algo():
  init_stuff()
  process_stuff()
  ...

あなたはどのように機能init_stuffするかを知っています。頭の中でそれはかなり単純ですが、すぐにそれを本当に必要としないので、あなたはそれを空の関数として宣言します。それはあなたのコードが厄介な詳細を気にすることなくコンパイルして実行できるようにします。

リリース済みアプリケーションのもう1つの用途は、継承を使用する場合です。プラットフォーム固有のコードの動作を定義する大きなクラスがあるとします。あなたはこれに似たロジックで終わるかもしれません:

init_filesystem();
access_files();
release_filesystem();

このコードは多くのプラットフォームで機能しますが、一部のプラットフォームではファイルシステムの初期化が不要な場合があります。次に、継承は次のようになります(C ++での仮想的な= 0は、派生クラスがこれらのメソッドを実装する必要があることを意味します):

class FileSystem{
  virtual void init_filesystem() = 0;
  virtual void access_files() = 0;
  virtual void release_filesystem() = 0;
};

次に、このクラス(インターフェース)の特定の実装は、これらのメソッドの一部に対して何もしない場合があります。あるいは、基本クラスは、init / releaseの仮想メソッドを宣言する代わりに、空のメソッドを宣言することもできます。

最後に(そして恥ずかしいことに)、非常に古いアプリケーションを維持することがあります。メソッドを削除すると問題が発生することを恐れています。これは、適切に理解されていない複雑な継承がある場合、または多くの関数ポインター(コールバック)がある場合に発生します。それらの中のコードを削除するだけで、何も壊さずに呼び出されます。


0

Rufflewindは、完成したプログラムで空の関数を使用する場合をカバーする優れた機能を果たしました。私の経験では、これは未完成のプログラムでより頻繁に使用される傾向があるので、これから作成する予定を計画し、実際に実装するまではコンパイルしておくことができます。つまり、通常は単なるプレースホルダーです。

ブレースを使用するCのような言語とは異なり、ブロックをマークするためにインデントを使用するため、これはpythonの場合に必要{}です。つまり、がない場合pass、パーサーはそれを空のままにするつもりなのか、忘れたのかを判断できませんでした。インクルードpassすることで、パーサーがはるかに単純になり、実装されていないブロックを探すときに検索するのに便利な単語が得られます。


1
未完成のコードのNotImplementedError場合、「エラーは黙って渡ってはならない」ため、スローはより適切なソリューションであり、ライブプログラムで未実装の関数を呼び出すとエラーになります。
ivan_pozdeev 2015年

場合によります。出荷するコードについては、そうです。しかし、それが1時間以内に実装する予定のコードであり、単体テストで作業している間、実装しないままにしているだけの場合は、単に実装を残さないほうが良いオプションかもしれません。多くの場合、私のワークフローを持つ1)書き込みスタブ方法であって、pass 2)メソッドの戻りが未定義としてテスト戻り値3)(テストが失敗確認することライトユニットテスト)4)を実装方法5)試験は今通過確認
ロボットゴート

0

これはPythonで期待することではありませんが、デバイスドライバーの世界では、(a)発生しないことがわかっている、または( b)気にしても気にしない。

これは、コールバック付きのCでも確認できます。たまに、コールバックを提供したと仮定して、それを呼び出そうとするコードが表示され、nullポインタのリスクは無視されます。その場合にできることは、空のコールバックルーチンを提供することだけです。(はい、私は特定のベンダーを念頭に置いています。)


pass特にクラスでコードを書くとき、すべてが完了する前に実行可能なものを必要とするとき、私はプレースホルダーとしてたくさん使用しました。これは本当にpythonに相当するもので{}、中括弧を使用しないためpythonは実行できません。その意味で、私が認識しているすべての言語でこれが許可されていpythonます。私たちが持っていたアセンブリの日にもさかのぼりNOPます。
Gort the Robot

@StevenBurnap、通常はそのようなことをするときに、ローカルのprintf( ">>>ルーチンXXXが呼び出される\ n");に相当するものを含めます。
John R. Strohm
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.