【Python】呼び出し可能オブジェクト
FastAPIのDepends周りでエラー(AttributeError)にハマったが、そもそもDepends()と関数、関数オブジェクト、呼び出し可能(不能)についての理解が曖昧だったため、わかる範囲で、まとめていく
呼び出し可能オブジェクト
クラスを定義したり、関数を定義したりすると、それらはかっこ「()」を付加し、そこ中に引数を指定することで、「呼び出す」ことができるようになる。こうしたオブジェクトのことを「呼び出し可能オブジェクト」と呼ぶ。
Pythonでは通常、クラスは呼び出し可能オブジェクトだが、そのインスタンスは呼び出し可能ではない。しかし、インスタンスを呼び出し可能オブジェクトのようにもできる。これには__call__特殊メソッドを定義すればよい。
引用:呼び出し可能オブジェクト
依存関係
依存関係が関数として宣言されているのを見てきました。しかし、依存関係を宣言する唯一の方法ではありません(おそらくその方が一般的でしょうが)。重要なのは、依存関係は "callable "でなければならないということです。
Pythonにおける "callable "とは、Pythonが関数のように "呼び出せる "ものを指します。つまり、(関数ではないかもしれませんが)何かのオブジェクトを持っていて、それを「呼び出せる」(実行できる) ことである。
引用:依存関係を作るものは何か
Dependsと関数呼び出しとの違いなども随時追記予定
Depends()のソースコード
class Depends:
def __init__(
self, dependency: Optional[Callable[..., Any]] = None, *, use_cache: bool = True
):
self.dependency = dependency
self.use_cache = use_cache
公式ソースコード:fastapi/fastapi/params.py
追記_20220608
Pythonの事例ではないけれど、関数名やクラス名のみで指定する時は、それはその(関数やクラス)オブジェクト自体ではなく、その関数やクラスが格納されているアドレス情報(「ポインタ」、「参照」)を指定していることになる、というようなイメージかな??
変数やdictの上書きとかで、値渡し、参照渡しの場面では注意してたけど、関数やクラスの呼び出しで「()なし」なんてあんまり考えたことなかったから良い勉強になりました。
enumerate()で、関数名を利用したい時に、「()なし」での指定などがあるが、そのうちその辺りの関連ももう少し掘り下げてみていきたい。。。
https://dixq.net/forum/viewtopic.php?t=17750
Pythonにおいて呼び出す対象は、関数だったり、クラス(などのオブジェクト)だったりするわけだが、公式ドキュメントによると、呼び出しとは、
というわけで、呼び出し可能なオブジェクトと「()」によって(0個以上の)引数の系列とともに呼び出すことが仕様となっている。
※では、「呼び出し可能オブジェクト」、「呼び出し不能」、「呼び出し」とは、という点は現状、私の力不足で、公式ドキュメントから発見できていない。。。
この記事が気に入ったらサポートをしてみませんか?