20

さまざまなモジュールの解析とイントロスペクションを行っていますが、組み込みモジュールを解析したくありません。現在、のような組み込みモジュール用の特別なタイプはありませんがtypes.BuiltinFunctionType、これを行うにはどうすればよいですか?

>>> import CornedBeef
>>> CornedBeef
<module 'CornedBeef' from '/meatish/CornedBeef.pyc'>
>>> CornedBeef.__file__
'/meatish/CornedBeef.pyc'
>>> del CornedBeef.__file__
>>> CornedBeef
<module 'CornedBeef' (built-in)>

Pythonによると、モジュールに属性がない場合、モジュールは明らかに組み込まれてい__file__ます。hasattr(SomeModule, '__file__')これは、モジュールが組み込まれているかどうかを確認する方法であることを意味しますか?確かに、それはに正確に一般的ではありませんがdel SomeModule.__file__、モジュールが組み込まれているかどうかを判断するためのより確実な方法はありますか?

4

4 に答える 4

11

sys.builtin_module_names

この Python インタープリターにコンパイルされるすべてのモジュールの名前を指定する文字列のタプル。(この情報は他の方法では利用できません — modules.keys() はインポートされたモジュールのみをリストします。)

于 2011-02-07T21:59:53.830 に答える
9

単に尋ねられたと考えるとbuiltins、受け入れられた答えは明らかに正しいです。

私の場合、標準ライブラリも探していました。これは、特定の Python ディストリビューションに同梱されているすべてのインポート可能なモジュールのリストを意味します。これに関する質問が何度か寄せられましたが、探していたすべてを含む回答が見つかりませんでした。

x私のユースケースは、Pythonimport xステートメントで任意のものを次のいずれかにバケット化していました。

  • Python stdlib + ビルトインに含まれています
  • サードパーティモジュールとしてインストール
  • ない

これは、virtualenvs またはグローバル インストールで機能します。スクリプトを実行している Python バイナリの分布を照会します。最後のチャンクは virtualenv の外に到達しますが、望ましい動作だと思います。

# You may need to use setuptools.distutils depending on Python distribution (from setuptools import distutils)
import distutils
import glob
import os
import pkgutil
import sys    

def get_python_library():

    # Get list of the loaded source modules on sys.path.
    modules = { 
        module
        for _, module, package in list(pkgutil.iter_modules())
        if package is False
    }

    # Glob all the 'top_level.txt' files installed under site-packages.
    site_packages = glob.iglob(os.path.join(os.path.dirname(os.__file__) 
                    + '/site-packages', '*-info', 'top_level.txt'))

    # Read the files for the import names and remove them from the modules list.
    modules -= {open(txt).read().strip() for txt in site_packages}

    # Get the system packages.
    system_modules = set(sys.builtin_module_names)

    # Get the just the top-level packages from the python install.
    python_root = distutils.sysconfig.get_python_lib(standard_lib=True)
    _, top_level_libs, _ = list(os.walk(python_root))[0]

    return sorted(top_level_libs + list(modules | system_modules))

戻り値

インポートのソートされたリスト:[..., 'imaplib', 'imghdr', 'imp', 'importlib', 'imputil', 'inspect', 'io', ...]

説明:

各グループが必要な理由が明確になるように、それをチャンクに分割しました。

  • modules

    • このpkgutil.iter_modules呼び出しは、読み込まれたすべてのモジュールをスキャンし、タプルsys.pathのジェネレーターを返します。(module_loader, name, ispkg)
    • ここではソースモジュールのみに関心があるため、これをセットにしてパッケージを除外します。
  • site_packages

    • 従来の site-packages ディレクトリの下にインストールされているすべてのパッケージのリストを取得し、リストから削除しますmodules。これは、サードパーティの deps にほぼ対応しています。
    • これは、正しくするのが最も難しい部分でした。またはのように、多くのことがほとんど機能しました。ただし、ソース ファイルにインポートされたときのモジュール名ではなく、PyPi 上のモジュール名を返します。特定の病的なパッケージは、次のように亀裂をすり抜けます。 pip.get_installed_distributionssitepip
      • requests-futuresとしてインポートされrequests_futuresます。
      • colors、これは実際ansicolorsには PyPi 上にあるため、合理的なヒューリスティックを混乱させます。
    • top_level.txtパッケージに が含まれていない使用頻度の低いモジュールがあることは確かです。しかし、これは私のユースケースの 100% をカバーしており、正しく構成されているすべてのもので動作するようです。
  • system_modules

    • sys明示的に要求しないと、 、gcerrnoおよびその他のオプション モジュールなどのシステム モジュールを取得できません。
  • top_level_libs

    • このdistutils.sysconfig.get_python_lib(standard_lib=True)呼び出しは、プラットフォームに依存しない標準ライブラリの最上位ディレクトリを返します。
    • これらは、他のモジュールと同じ python パスの下に存在しない可能性があるため、見落としがちです。OSX 上で virtualenv を実行している場合、これらのモジュールは実際にはシステム インストールからインポートされます。これらのモジュールにはemail、 、loggingxmlおよびその他のいくつかが含まれます。

結論

私の 2013 MacBookPro では、python2.7インストール用に 403 個のモジュールが見つかりました。

   >>> print(sys.version)
   2.7.10 (default, Jul 13 2015, 12:05:58)
   [GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)]
   >>> print(sys.hexversion)
   34015984
   >>> python_stdlib = get_python_libirary()
   >>> len(python_stdlib)
   403

コードの要点をまとめて出力します。クラスが欠けている、または偽のモジュールが含まれていると思われる場合は、それについてお知らせください。

*代替案

  • この記事を書いている間、私はpipand setuptoolsAPI について掘り下げました。単一のモジュールを介してこの情報を取得することは可能ですが、実際にはその API の使い方を知る必要があります。

  • sixこれを始める前に、 にはこの問題に特化した機能があると言われました。存在するのは理にかなっていますが、私はそれを自分で見つけることができませんでした.

于 2016-05-15T20:36:13.970 に答える
4

モジュール名が組み込みモジュールと一致するかどうかを確認するために使用できますimp.is_builtinが、実際にモジュールオブジェクトを確実にイントロスペクトする方法は考えられません。

次のことも試してみてください。

>>> import imp
>>> f, path, desc = imp.find_module("sys")
>>> desc
('', '', 6)
>>> desc[2] == imp.C_BUILTIN
True
于 2011-02-07T15:03:08.187 に答える
2

「組み込み」とは、C で書かれたという意味ですか、それとも標準ライブラリの一部という意味ですか? 最初のことを意味する場合は、探すの__file__が正しいことです。ご覧のとおり、Python インタープリターでさえ、 の存在を__file__組み込み性の指標として使用しています。

「標準ライブラリの一部」を意味する場合、それを判断するのは非常に困難です。

于 2011-02-07T14:48:17.120 に答える