[英]How can I tell if a package/module is part of Python's std library? without a 3rd party library
我想查看/限制應用程序中的依賴項,並且我想忽略給定 Python 版本的標准庫中已經包含的所有內容。 什么是簡單的 Pythonic 方式來做到這一點?
我已經做了一些工作,但由於這似乎是一個相當基本的問題,我想知道是否有更好的方法。 而且我的解決方案現在看起來很危險地依賴於平台(我在 macos 上,它可能適用於 Linux,懷疑它是否適用於 Windows)。
基本上,我查看已知 stdlib 模塊所在的目錄,然后從中獲取 python 文件目錄。
#parent directory for the `os` module.
pa_lib_builtins = Path(os.__file__).parent
s_stdlib = set()
for pa_py in pa_lib_builtins.glob("*"):
#skip some directories
if pa_py.name in {"site-packages", "lib-dynload"}:
continue
#add modules/packages
if pa_py.suffix == ".py":
#a direct module, add it.
s_stdlib.add(pa_py.stem)
else:
#it's a package, add it
if pa_py.is_dir():
s_stdlib.add(pa_py.name)
#looks too operating-system dependent... add the stuff in lib-dynload
pa_lib_dynload = pa_lib_builtins / "lib-dynload"
for pa in pa_lib_dynload.glob("*"):
s_stdlib.add(pa_py.stem.split(".")[0])
#add stuff that I can't find on the file system but is registered as built-in
#this brings in `sys`, for example.
for name in sys.builtin_module_names:
s_stdlib.add(name)
lib-dynload
的內容(我只抓住第一個.
的左側)。.
..
_asyncio.cpython-36m-darwin.so
_bisect.cpython-36m-darwin.so
_blake2.cpython-36m-darwin.so
我有更好的方法嗎? 請注意,我並不太擔心誤報。 例如,將__pycache__
視為一個模塊並沒有真正的傷害,因為我不需要擔心任何import __pycache__
。
這主要通過在運行時自省文件系統來解決問題。 與文檔解析不同,它對當前操作系統上實際安裝的內容很敏感。 它也可以在沒有互聯網訪問的情況下工作。
那么 - 從比較 3.6 的https://github.com/jackmaney/python-stdlib-list ? :
msilib
或msvcr
。 ✅posixpath
。 ✅稍后我將針對 Windows 和 Linux 運行此程序並根據需要進行更新,但我預計它應該可以輕松工作。
def get_stdlib_names(try_import=False):
"""
get stdlib module/package names
by globbing file system
"""
import pathlib
Path = pathlib.Path
pa_dyn_name = os_specific = pa_dyn = None
s_stdlib0 = set()
try:
# Unix services
import syslog as os_specific
except ModuleNotFoundError:
try:
# Windows services
import msilib as os_specific
except ModuleNotFoundError:
pass
# parent directory for `pathlib` itself
pa_stdlib = Path(pathlib.__file__).parent
# OS-dependent/dynamic libraries
if os_specific:
pa_dyn = Path(os_specific.__file__).parent
pa_dyn_name = pa_dyn.name
for pa_py in pa_stdlib.glob("*"):
# skip directories we don't want
if pa_py.name in {"site-packages", pa_dyn_name, "test"}:
continue
# add modules (*.py)/packages (directories
if pa_py.suffix == ".py":
s_stdlib0.add(pa_py.stem)
else:
if pa_py.is_dir():
s_stdlib0.add(pa_py.name)
# load dynamic libraries
if os_specific:
# consider qualifying glob with `.dll`/`.so` extension
for pa in pa_dyn.glob("*"):
name = pa.stem.split(".")[0]
s_stdlib0.add(name)
# add stuff not on the file system, like `sys`
for name in sys.builtin_module_names:
s_stdlib0.add(name)
# skip `_` aliases for modules:
# .../lib/python3.6/asyncio/__init__.py
# .../lib/python3.6/lib-dynload/_asyncio.cpython-36m-darwin.so
s_stdlib0 = {
name
for name in s_stdlib0
if (not name.startswith("_"))
# special cases
or name in ("__future__ _thread _dummy_thread".split())
}
s_stdlib0.add("__main__")
# do we want to check if we can import it?
if not try_import:
return s_stdlib0
s_stdlib = set()
for name in s_stdlib0:
# side effects/won't import
if name in ("antigravity", "this", "__main__"):
s_stdlib.add(name)
continue
try:
importlib.import_module(name)
s_stdlib.add(name)
except ModuleNotFoundError as e:
pass
return s_stdlib
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.