質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
import

自身のプラットフォーム・プログラム・データセットに対して、外部ソースを取り込むプロセスをimportと呼びます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

2107閲覧

実行ファイルのモジュールを取得する方法

unknown_user

総合スコア68

import

自身のプラットフォーム・プログラム・データセットに対して、外部ソースを取り込むプロセスをimportと呼びます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/02/07 18:11

外部ファイルのモジュールはimport my_moduleで取得できますが、実行ファイルのモジュールを取得する方法はありますか?

python

1import inspect 2import my_module 3 4print(inspect.getmembers(my_module, inspect.isfunction))

のようにな感じで、inspect.getmembersの引数に実行ファイルのモジュールを指定したいというモチベーションです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

やりたいことが、
print(inspect.getmembers(my_module, inspect.isfunction))
であるというのを読んでいませんでした。

それでしたら、以下です。

python

1import sys 2import inspect 3 4print(inspect.getmembers(sys.modules[__name__], inspect.isfunction))

ただ、もう一つの質問の回答で書いたように、unknown_userさんが欲しいものが出てくる保証はありません。

python

1>>> import sys 2>>> import inspect 3 4>>> def f(): 5... pass 6... 7>>> from glob import glob 8>>> print(inspect.getmembers(sys.modules[__name__], inspect.isfunction)) 9[('f', <function f at 0x000001EFFD659EE0>), ('glob', <function glob at 0x000001EFFA7D1280>)]

これが起きるのは、globのような標準モジュールの中にもユーザ定義関数globが入っていることと、from モジュール import 名前
を実行したときに、その名前は現在のモジュールのグローバル変数として登録されるためです。

-------------------------------------
以下は関係なかったようですが参考のために残しておきます。

誤りがあったので修正しました。

モジュール名というのが、モジュールの名前属性であるのか、ファイル名であるのかで答えが違います。

モジュールの名前属性であれば、

python

1import sys 2print(sys.modules[__name__].__name__)

です。

$ python - ファイル名.py
の場合は、ファイル名が表示されます。

$ python ファイル名.py
の場合は、常に'main'となっています。
Linuxでファイルに実行属性をつけてて以下のように実行した場合も
$ ./ファイル名.py
常に'main'となっています。

モジュールのファイル名であれば、
$ python ファイル名.py
の場合や
$ ./ファイル名.py
の場合は

python

1import sys 2print(sys.modules[__name__].__file__)

です。

$ python -m ファイル名.py
の場合は

python

1import sys 2print(sys.modules[__name__].__name__)

です。

投稿2021/02/07 22:08

編集2021/02/08 07:12
ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

unknown_user

2021/02/08 10:19

ありがとうございます。`sys.modules[__name__]`で取得できるのですね。 `inspect.isfunction`だと不十分そうですね... 前の質問で教えていただいた`v.__module__ == my_module.__name__`でフィルタリングしてみようと思います。 また、実行方法の違いで`sys.modules[__name__].__name__`が変わることも教えていただき感謝します。 このあたりは調べてもあまり情報が見つからなかったので理解が深まりました。
guest

0

python

1if __name__ == "__main__": 2 main()

というイディオムを知っていれば分かっているはずですが、実行ファイルのモジュールは常に名前が__main__です。

https://docs.python.org/ja/3/library/main.html#module-main


追記

したがってそれ以外のモジュールからは常に

python

1import __main__

としてインポートすることができるということです。

循環参照にならないように気をつけなければいけない循環参照を意識する必要があることと、対話環境などでは__main__は見つからずにエラーになることなどが注意点です。


意図的に循環参照したコードの例

a.py

python

1import b 2 3def x(): 4 return 0

b.py

python

1import __main__ 2 3# この時点でxは未定義なのでエラーになる 4# __main__に含まれる関数を探してもそこにxはない 5print(__main__.x())

投稿2021/02/07 23:44

編集2021/02/09 23:46
quickquip

総合スコア11235

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

quickquip

2021/02/07 23:46

実行ファイルのモジュール が曖昧です。想像できる候補のもう一つの方ということで回答しておきます。
unknown_user

2021/02/08 10:30

ありがとうございます。期待していた回答は後者の`import __main__`の方です。 `__main__`はimportしたあとでも関数定義をするとモジュールに関数が追加されるのが面白いですね。 `inspect.getmembers(__main__, inspect.isfunction)`はこのメソッドを実行したタイミングまでに定義した関数を取得できました。
unknown_user

2021/02/08 10:34

恐縮ですが`import __main__`で発生しうる循環参照はどういったパターンなのか教えていただけますでしょうか?
quickquip

2021/02/09 23:40

循環参照になるので気を付けてください が正確でしたね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問