Help us understand the problem. What is going on with this article?

Pythonで関数名から実装内容を出力する

More than 1 year has passed since last update.

TL;DR

  • inspectを使う
  • Jupyter Notebookでは、??func_name or func_name??で同様の結果を得られる。【情報提供元: @na90ya 様】

目的

「サンプルコードでしれっと使われてる関数の実装を知りたい」「でも元ソースを追うのはつらい」といったときがありました。

どうせなら、REPL上で簡単に確認できないものかと常々思ってました。

例えば、こんなソース

github.com/tensorflow/models/research/slim/mobilenet/mobilenet_v2.py
...
import tensorflow as tf

from nets.mobilenet import conv_blocks as ops
from nets.mobilenet import mobilenet as lib

slim = tf.contrib.slim
op = lib.op

expand_input = ops.expand_input_by_factor

# pyformat: disable
# Architecture: https://arxiv.org/abs/1801.04381
V2_DEF = dict(
    defaults={
        # Note: these parameters of batch norm affect the architecture
        # that's why they are here and not in training_scope.
        (slim.batch_norm,): {'center': True, 'scale': True},
        (slim.conv2d, slim.fully_connected, slim.separable_conv2d): {
            'normalizer_fn': slim.batch_norm, 'activation_fn': tf.nn.relu6
...

ここのtf.nn.relu6というメソッドが一体何をしているのか知りたい。大方予想はつくが、予想と違うと後々困る。

やり方

調べたら普通にありました。

ソース:https://stackoverflow.com/questions/427453/how-can-i-get-the-source-code-of-a-python-function

ここによると、inspectモジュールに、今回の用途を満たしてくれる機能が詰まってるようです。

今回は、単純に実装だけわかればいいので、inspectモジュールの中の、getsourceという関数を使用します。
これは、関数名を引数として与えることにより、実装内容を返してくれる関数のようです。

以下のような感じで使用することができます。

[musaprg@sylveon ~]$ python 
Python 3.6.8 |Anaconda custom (64-bit)| (default, Dec 30 2018, 01:22:34)
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" o
>>> import tensorflow as tf
>>> lines = inspect.getsource(tf.nn.relu6)
>>> print(lines)
@tf_export("nn.relu6")
def relu6(features, name=None):
  """Computes Rectified Linear 6: `min(max(features, 0), 6)`.

  Source: [Convolutional Deep Belief Networks on CIFAR-10. A.
  Krizhevsky](http://www.cs.utoronto.ca/~kriz/conv-cifar10-aug2010.pdf)

  Args:
    features: A `Tensor` with type `float`, `double`, `int32`, `int64`, `uint8`,
      `int16`, or `int8`.
    name: A name for the operation (optional).

  Returns:
    A `Tensor` with the same type as `features`.
  """
  with ops.name_scope(name, "Relu6", [features]) as name:
    features = ops.convert_to_tensor(features, name="features")
    return gen_nn_ops.relu6(

もっと色々できるみたいですね。詳しくは公式docへ。

https://docs.python.jp/3/library/inspect.html

Jupyter Notebookの場合

Jupyter Notebookを使っている場合は、IPython自体にinspectモジュールと同様の出力を得られる構文が存在しました。

情報提供してくださった @na90ya 様、ありがとうございます!

やり方

調べたい関数名をfunc_nameとすると、以下のように記述することで、inspect.getsourceと同様の出力を得ることができます。

??func_name
func_name??

??は、目的の関数の前後どちらにつけても動作するみたいです。

musaprg
スニペット類の著作権は「CC0 1.0」です
misw
プログラミング・2D/3DCG・DTM・シナリオ・動画製作等を一手に引き受ける、早稲田大学公認のデジタル創作サークル
https://misw.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away