関数の引数のデフォルト値を取得しますか?
質問
この関数について
def eat_dog(name, should_digest=True):
print "ate dog named %s. Digested, too? %" % (name, str(should_digest))
関数の外部で、その引数やデフォルト値を読み取りたいのです。つまり、この具体的な例では
name
にはデフォルト値がなく (つまり必須引数であること)、また
True
はデフォルト値として
should_digest
.
私が意識しているのは
inspect.getargspec()
は、引数やデフォルト値についての情報を与えてくれますが、この2つの間に何の関連性も見出せません。
ArgSpec(args=['name', 'should_digest'], varargs=None, keywords=None, defaults=(True,))
この出力から、どうすれば
True
(その中の
defaults
タプル) のデフォルト値は
should_digest
?
さらに、私は問題にアプローチするための "ask for forgiveness" モデルについて知っていますが、残念ながらそのエラーからの出力は、不足している引数の名前を教えてはくれません。
>>> eat_dog()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: eat_dog() takes at least 1 argument (0 given)
文脈を説明すると(なぜこれをやりたいのか)、私はJSON APIを介してモジュール内の関数を公開しています。呼び出し側が特定の関数引数を省略した場合、省略された特定の関数引数を指定する特定のエラーを返したいのです。クライアントが引数を省略しても、関数の署名で提供されるデフォルトがある場合、そのデフォルトを使用したいと思います。
どのように解決するのですか?
Python3.x
Python3.xの世界では、おそらくは
Signature
オブジェクトを使うべきでしょう。
import inspect
def get_default_args(func):
signature = inspect.signature(func)
return {
k: v.default
for k, v in signature.parameters.items()
if v.default is not inspect.Parameter.empty
}
Python2.x (古い答え)
args/defaultsは、次のように組み合わせることができます。
import inspect
a = inspect.getargspec(eat_dog)
zip(a.args[-len(a.defaults):],a.defaults)
ここで
a.args[-len(a.defaults):]
はデフォルト値を持つ引数で、明らかに
a.defaults
は対応するデフォルト値である。
の出力を渡すこともできます。
zip
の出力を
dict
のコンストラクタに追加し、キーワード展開に適したマッピングを作成します。
ドキュメントを見ると、この解決策はpython2.6またはそれ以降でしか動作しないようです。
inspect.getargspec
を返すと仮定しているからです。
という名前のタプル
. 以前のバージョンでは
正規のタプル
を返しますが、それに応じて修正するのは非常に簡単でしょう。 以下は、古い(そして新しい)バージョンで動作するバージョンです。
import inspect
def get_default_args(func):
"""
returns a dictionary of arg_name:default_values for the input function
"""
args, varargs, keywords, defaults = inspect.getargspec(func)
return dict(zip(args[-len(defaults):], defaults))
そういえば
return dict(zip(reversed(args), reversed(defaults)))
も動作し、人によってはより直感的に理解できるかもしれません。
関連
-
[解決済み] 関数デコレータを作成し、それらを連鎖させるには?
-
[解決済み] 関数内でグローバル変数を使用する
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] 辞書を値で並べ替えるにはどうしたらいいですか?
-
[解決済み] 最小限の驚き」と「変更可能なデフォルトの引数
-
[解決済み] モジュールの関数名(文字列)を使って、モジュールの関数を呼び出す。
-
[解決済み] インスタンスのクラス名を取得する?
-
[解決済み] Pythonでシングルトンを作成する
-
[解決済み】Pythonで2つの変数の論理xorを取得するにはどうすればいいですか?
-
[解決済み] Python 3でバイナリデータを標準出力に書き込むには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] PythonでファイルのMD5チェックサムを計算するには?重複
-
[解決済み] DataFrameに日付間の日数カラムを追加する pandas
-
[解決済み] python-requests モジュールからのすべてのリクエストをログに記録します。
-
[解決済み] tensorflowのCPUのみのインストールでダイナミックライブラリ 'cudart64_101.dll' を読み込めなかった
-
[解決済み] matplotlib でプロットの軸、目盛、ラベルの色を変更する方法
-
[解決済み] Celeryタスクのユニットテストはどのように行うのですか?
-
[解決済み] virtualenv の `--no-site-packages` オプションを元に戻す。
-
[解決済み] Pythonの文字列の前にあるbという接頭辞は何を意味するのですか?
-
[解決済み] あるメソッドが複数の引数のうち1つの引数で呼び出されたことを保証する
-
[解決済み] Python の sorted() はどのようなアルゴリズムを使っているのですか?重複