2016-03-22 7 views
-1

私たちは、ユーザーがオプションのpythonコールバック関数をオーバーライドできるようにするアプリケーションを用意しています。cpython呼び出しで空白/空の関数を検出していますか?

例シリアルデータを受信したとき、任意のユーザ定義のPython関数が呼び出される:

def onDataReceived(bytes, timeStamp, address, peer): 
    return 

これは、ソースファイルからではなく、アプリケーションにコンパイル。

アプリケーションはC++のリアルタイム処理エンジンであるため、cpythonインタプリタを呼び出すとかなりのオーバーヘッドが消費されることに注意してください。私はプリコンパイルされた関数へのアクセスを持っているので、テキストを手で直接構文解析することなく、上記のように空白/空が空であるかどうかを判断する方法はありますか?

ありがとうございました。

+0

@mswなぜ質問に答えることができないのか混乱しています。 Antti Haapalaは以下の非常に実行可能なソリューションを提供しています。 – rbairos

+0

インタープリタへの呼び出しは大丈夫ですか?あなたの質問はそうでなければ示唆します。 – msw

+0

私はインタプリタを呼び出し、前述のようにコードがアプリケーションでコンパイルされるので結果をキャッシュすることができるので、テキスト編集が行われたときにそれを検出するのは簡単です。私はちょうど最後の関数を後で不必要に繰り返し呼び出すことはしたくない。 私は彼の答えをとり、私が現在実装しているように、CPythonの同等のPyFunctionObjectを直接調べることもできます。 これに照らして依然として質問が下位投票に値するとは思わないでください。 – rbairos

答えて

2

func.__code__.co_code(Python 3の場合はco_codeの代わりにfunc_codeを使用してください)を確認できます。これは、関数のバイトコードを含むバイト文字列です。したがって

def empty(): 
    pass 

empty_code = empty.__code__.co_code 

def is_empty(func): 
    return hasattr(func, '__code__') and func.__code__.co_code == empty_code 

注ドキュメンテーション文字列を持っている機能は、わずかに異なるバイトコードを持っている(:

>>> def foo(): 
...  return 
... 
>>> def bar(): 
...  pass 
... 
>>> import dis 
>>> dis.dis(foo) 
    2   0 LOAD_CONST    0 (None) 
       3 RETURN_VALUE 
>>> dis.dis(bar) 
    2   0 LOAD_CONST    0 (None) 
       3 RETURN_VALUE 
>>> foo.__code__.co_code 
b'd\x00\x00S' 

だからあなたが知られている空の関数に対して__code__.co_codeを比較する関数を作成することができますdocstringは一定のスロットを占有します)。より洗練されたものについては、バイトコード逆アセンブラ出力の出力を調べることができます。

+0

ありがとうございました。 funcに__code__属性が含まれていない場合がありますか? – rbairos

+1

@rbairosは、 '__call__'や組み込みの/ C関数やバインドされたメソッドを持つオブジェクトです。 –

関連する問題