LoginSignup
0
0

More than 3 years have passed since last update.

[Python]関数名に関数名を代入してみた

Posted at

結論

代入された方は代入した方に書き換えられます。以下、実験結果。

Colab
#funcを定義
def func(x, y):
  return x - y

func(1, 2) # -1


#func0を定義
def func0():
  return None

func0() #何も出力されない


#関数名に関数名を代入
func0 = func

func(1, 3) # -2

func0(1, 3) # -2

なぜこんなことを調べたのか

PyTorchのModuleクラス__call__メソッドがなぜか上記のように一度_call_implで設定してから__call__に代入するという設定になっていたから。
どなたかどうしてこのような面倒な記述をPyTorchがしていたのかを教えてください(切実)。以下がそのソースコードです。

torch.nn.modules.module
def _call_impl(self, *input, **kwargs):
        for hook in itertools.chain(
                _global_forward_pre_hooks.values(),
                self._forward_pre_hooks.values()):
            result = hook(self, input)
            if result is not None:
                if not isinstance(result, tuple):
                    result = (result,)
                input = result
        if torch._C._get_tracing_state():
            result = self._slow_forward(*input, **kwargs)
        else:
            result = self.forward(*input, **kwargs)
        for hook in itertools.chain(
                _global_forward_hooks.values(),
                self._forward_hooks.values()):
            hook_result = hook(self, input, result)
            if hook_result is not None:
                result = hook_result
        if (len(self._backward_hooks) > 0) or (len(_global_backward_hooks) > 0):
            var = result
            while not isinstance(var, torch.Tensor):
                if isinstance(var, dict):
                    var = next((v for v in var.values() if isinstance(v, torch.Tensor)))
                else:
                    var = var[0]
            grad_fn = var.grad_fn
            if grad_fn is not None:
                for hook in itertools.chain(
                        _global_backward_hooks.values(),
                        self._backward_hooks.values()):
                    wrapper = functools.partial(hook, self)
                    functools.update_wrapper(wrapper, hook)
                    grad_fn.register_hook(wrapper)
        return result

    __call__ : Callable[..., Any] = _call_impl
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0