封裝 (numpy.distutils)#

警告

numpy.distutils 已棄用,將在 Python >= 3.12 中移除。有關更多詳細資訊,請參閱 numpy.distutils 的狀態與遷移建議

警告

請注意,setuptools 經常進行主要發行,這些發行版本可能包含會破壞 numpy.distutils 的變更,而 numpy.distutils不再為新的 setuptools 版本更新。因此,建議在您的建置組態中為與您的建置搭配使用的最後已知 setuptools 版本設定版本上限。

NumPy 提供了增強的 distutils 功能,以更輕鬆地建置和安裝子套件、自動產生程式碼,以及使用 Fortran 編譯程式庫的擴充模組。在 numpy.distutils.misc_util 中也提供了一個有用的 Configuration 類別,它可以更輕鬆地建構關鍵字引數以傳遞給 setup 函式(透過傳遞從類別的 todict() 方法取得的字典)。更多資訊請參閱 numpy.distutils 使用者指南

連結程式庫(例如 BLAS 和 LAPACK)的選擇和位置,以及包含路徑和其他此類建置選項,可以在 NumPy 根儲存庫中的 site.cfg 檔案或您主目錄中的 .numpy-site.cfg 檔案中指定。請參閱 NumPy 儲存庫或 sdist 中包含的 site.cfg.example 範例檔案以取得文件。

numpy.distutils 中的模組#

ccompiler

ccompiler_opt

提供 CCompilerOpt 類別,用於處理 CPU/硬體最佳化,從剖析命令引數開始,到管理 CPU 基準和可調度功能之間的關係,也產生所需的 C 標頭,並以適當的編譯器旗標結束來源的編譯。

cpuinfo.cpu

core.Extension(name, sources[, ...])

參數:

exec_command

exec_command

log.set_verbosity(v[, force])

system_info.get_info(name[, notfound_action])

notfound_action

system_info.get_standard_file(fname)

從以下位置傳回名為 'fname' 的檔案清單:1) 系統範圍目錄(此模組的目錄位置)2) 使用者 HOME 目錄 (os.environ['HOME']) 3) 本機目錄

Configuration 類別#

class numpy.distutils.misc_util.Configuration(package_name=None, parent_name=None, top_path=None, package_path=None, **attrs)[source]#

為給定的套件名稱建構組態實例。如果 parent_name 不是 None,則將套件建構為 parent_name 套件的子套件。如果 top_pathpackage_path 都是 None,則它們會被假定為等於建立此實例的檔案路徑。numpy 發行版中的 setup.py 檔案是如何使用 Configuration 實例的好範例。

todict()[source]#

傳回與 distutils setup 函式的關鍵字引數相容的字典。

範例

>>> setup(**config.todict())                           
get_distribution()[source]#

傳回 self 的 distutils 發行物件。

get_subpackage(subpackage_name, subpackage_path=None, parent_name=None, caller_level=1)[source]#

傳回子套件組態的清單。

參數:
subpackage_namestr 或 None

要取得組態的子套件名稱。subpackage_name 中的 '*' 會被視為萬用字元。

subpackage_pathstr

如果為 None,則路徑會被假定為本機路徑加上 subpackage_name。如果在 subpackage_path 中找不到 setup.py 檔案,則會使用預設組態。

parent_namestr

父名稱。

add_subpackage(subpackage_name, subpackage_path=None, standalone=False)[source]#

將子套件新增至目前的 Configuration 實例。

這在 setup.py 腳本中將子套件新增至套件時很有用。

參數:
subpackage_namestr

子套件的名稱

subpackage_pathstr

如果給定,子套件路徑,例如子套件位於 subpackage_path / subpackage_name 中。如果為 None,則假定子套件位於本機路徑 / subpackage_name 中。

standalonebool
add_data_files(*files)[source]#

將資料檔案新增至組態 data_files。

參數:
files序列

引數可以是

  • 2 序列(<datadir 字首>,<資料檔案路徑>)

  • 資料檔案的路徑,其中 python datadir 字首預設為套件目錄。

註解

檔案序列中每個元素的格式非常彈性,允許在從套件取得檔案的位置與它們最終應安裝在系統上的位置之間進行多種組合。最基本的使用方式是檔案引數序列的元素為簡單的檔案名稱。這會導致本機路徑中的該檔案安裝到 self.name 套件(套件路徑)的安裝路徑。檔案引數也可以是相對路徑,在這種情況下,整個相對路徑將安裝到套件目錄中。最後,檔案可以是絕對路徑名稱,在這種情況下,將在絕對路徑名稱中找到檔案,但安裝到套件路徑。

可以透過傳遞 2 元組作為檔案引數來擴充此基本行為。元組的第一個元素應指定相對路徑(在套件安裝目錄下),其餘的檔案序列應安裝到該路徑(它與來源發行版中的檔案名稱無關)。元組的第二個元素是要安裝的檔案序列。此序列中的檔案可以是檔案名稱、相對路徑或絕對路徑。對於絕對路徑,檔案將安裝在最上層套件安裝目錄中(無論第一個引數是什麼)。檔案名稱和相對路徑名稱將安裝在套件安裝目錄下,路徑名稱作為元組的第一個元素給定。

安裝路徑的規則

  1. file.txt -> (., file.txt)-> parent/file.txt

  2. foo/file.txt -> (foo, foo/file.txt) -> parent/foo/file.txt

  3. /foo/bar/file.txt -> (., /foo/bar/file.txt) -> parent/file.txt

  4. *.txt -> parent/a.txt, parent/b.txt

  5. foo/*.txt`` -> parent/foo/a.txt, parent/foo/b.txt

  6. */*.txt -> (*, */*.txt) -> parent/c/a.txt, parent/d/b.txt

  7. (sun, file.txt) -> parent/sun/file.txt

  8. (sun, bar/file.txt) -> parent/sun/file.txt

  9. (sun, /foo/bar/file.txt) -> parent/sun/file.txt

  10. (sun, *.txt) -> parent/sun/a.txt, parent/sun/b.txt

  11. (sun, bar/*.txt) -> parent/sun/a.txt, parent/sun/b.txt

  12. (sun/*, */*.txt) -> parent/sun/c/a.txt, parent/d/b.txt

另一個附加功能是資料檔案的路徑實際上可以是一個不帶引數並傳回資料檔案實際路徑的函式。當資料檔案在建置套件時產生時,這很有用。

範例

將檔案新增至要包含在套件中的 data_files 清單。

>>> self.add_data_files('foo.dat',
...     ('fun', ['gun.dat', 'nun/pun.dat', '/tmp/sun.dat']),
...     'bar/cat.dat',
...     '/full/path/to/can.dat')                   

會將這些資料檔案安裝到

<package install directory>/
 foo.dat
 fun/
   gun.dat
   nun/
     pun.dat
 sun.dat
 bar/
   car.dat
 can.dat

其中 <套件安裝目錄> 是套件(或子套件)目錄,例如 '/usr/lib/python2.4/site-packages/mypackage' ('C: Python2.4 Lib site-packages mypackage') 或 '/usr/lib/python2.4/site- packages/mypackage/mysubpackage' ('C: Python2.4 Lib site-packages mypackage mysubpackage')。

add_data_dir(data_path)[source]#

遞迴地將 data_path 下的檔案新增至 data_files 清單。

遞迴地將 data_path 下的檔案新增至要安裝(和發行)的 data_files 清單。data_path 可以是相對路徑名稱、絕對路徑名稱,或是 2 元組,其中第一個引數顯示資料目錄應安裝到安裝目錄中的哪個位置。

參數:
data_pathseq 或 str

引數可以是

  • 2 序列(<datadir 後綴>,<資料目錄路徑>)

  • 資料目錄的路徑,其中 python datadir 後綴預設為套件目錄。

註解

安裝路徑的規則

foo/bar -> (foo/bar, foo/bar) -> parent/foo/bar
(gun, foo/bar) -> parent/gun
foo/* -> (foo/a, foo/a), (foo/b, foo/b) -> parent/foo/a, parent/foo/b
(gun, foo/*) -> (gun, foo/a), (gun, foo/b) -> gun
(gun/*, foo/*) -> parent/gun/a, parent/gun/b
/foo/bar -> (bar, /foo/bar) -> parent/bar
(gun, /foo/bar) -> parent/gun
(fun/*/gun/*, sun/foo/bar) -> parent/fun/foo/gun/bar

範例

例如,假設來源目錄包含 fun/foo.dat 和 fun/bar/car.dat

>>> self.add_data_dir('fun')                       
>>> self.add_data_dir(('sun', 'fun'))              
>>> self.add_data_dir(('gun', '/full/path/to/fun'))

會將資料檔案安裝到以下位置

<package install directory>/
  fun/
    foo.dat
    bar/
      car.dat
  sun/
    foo.dat
    bar/
      car.dat
  gun/
    foo.dat
    car.dat
add_include_dirs(*paths)[source]#

將路徑新增至組態 include 目錄。

將給定的路徑序列新增至 include_dirs 清單的開頭。此清單對於目前套件的所有擴充模組都是可見的。

add_headers(*files)[source]#

將可安裝的標頭新增至組態。

將給定的檔案序列新增至標頭清單的開頭。依預設,標頭將安裝在 <python-include>/<self.name.replace('.','/')>/ 目錄下。如果 files 的項目是元組,則其第一個引數指定相對於 <python-include> 路徑的實際安裝位置。

參數:
filesstr 或 seq

引數可以是

  • 2 序列(<includedir 後綴>,<標頭檔案路徑>)

  • 標頭檔案的路徑,其中 python includedir 後綴將預設為套件名稱。

add_extension(name, sources, **kw)[source]#

將擴充功能新增至組態。

建立 Extension 實例並將其新增至 ext_modules 清單。此方法也採用以下選用的關鍵字引數,這些引數會傳遞至 Extension 建構函式。

參數:
namestr

擴充功能的名稱

sourcesseq

來源清單。來源清單可能包含函式(稱為來源產生器),這些函式必須將擴充功能實例和建置目錄作為輸入,並傳回來源檔案或來源檔案清單或 None。如果傳回 None,則不會產生任何來源。如果在處理所有來源產生器後,Extension 實例沒有來源,則不會建置任何擴充模組。

include_dirs
define_macros
undef_macros
library_dirs
libraries
runtime_library_dirs
extra_objects
extra_compile_args
extra_link_args
extra_f77_compile_args
extra_f90_compile_args
export_symbols
swig_opts
depends

depends 清單包含擴充模組的來源所依賴的檔案或目錄路徑。如果 depends 清單中的任何路徑比擴充模組新,則會重建模組。

language
f2py_options
module_dirs
extra_infodict 或 list

要附加到關鍵字的關鍵字字典或字典清單。

註解

self.paths(…) 方法會套用至所有可能包含路徑的清單。

add_library(name, sources, **build_info)[source]#

將程式庫新增至組態。

參數:
namestr

擴充功能的名稱。

sources序列

來源清單。來源清單可能包含函式(稱為來源產生器),這些函式必須將擴充功能實例和建置目錄作為輸入,並傳回來源檔案或來源檔案清單或 None。如果傳回 None,則不會產生任何來源。如果在處理所有來源產生器後,Extension 實例沒有來源,則不會建置任何擴充模組。

build_infodict,選用

允許使用以下金鑰

  • depends

  • macros

  • include_dirs

  • extra_compiler_args

  • extra_f77_compile_args

  • extra_f90_compile_args

  • f2py_options

  • language

add_scripts(*files)[source]#

將腳本新增至組態。

將檔案序列新增至 scripts 清單的開頭。腳本將安裝在 <字首>/bin/ 目錄下。

add_installed_library(name, sources, install_dir, build_info=None)[source]#

與 add_library 類似,但指定的程式庫已安裝。

distutils 搭配使用的大多數 C 程式庫僅用於建置 python 擴充功能,但透過此方法建置的程式庫將會安裝,以便第三方套件可以重複使用它們。

參數:
namestr

已安裝程式庫的名稱。

sources序列

程式庫的來源檔案清單。請參閱 add_library 以取得詳細資訊。

install_dirstr

安裝程式庫的路徑,相對於目前的子套件。

build_infodict,選用

允許使用以下金鑰

  • depends

  • macros

  • include_dirs

  • extra_compiler_args

  • extra_f77_compile_args

  • extra_f90_compile_args

  • f2py_options

  • language

傳回:
None

註解

對抗指定的 C 程式庫連結所需選項的最佳編碼方式是使用 "libname.ini" 檔案,並使用 get_info 來擷取所需的選項(請參閱 add_npy_pkg_config 以取得更多資訊)。

add_npy_pkg_config(template, install_dir, subst_dict=None)[source]#

從範本產生並安裝 npy-pkg 組態檔案。

template 產生的組態檔案會安裝在給定的安裝目錄中,並使用 subst_dict 進行變數替換。

參數:
templatestr

範本的路徑,相對於目前的套件路徑。

install_dirstr

npy-pkg 組態檔案的安裝位置,相對於目前的套件路徑。

subst_dictdict,選用

如果給定,當安裝時,範本檔案中任何形式為 @key@ 的字串都將由 subst_dict[key] 取代。安裝字首始終透過變數 @prefix@ 提供,因為安裝字首不容易從 setup.py 可靠地取得。

註解

這適用於標準安裝和就地建置,即 @prefix@ 指的是就地建置的來源目錄。

範例

config.add_npy_pkg_config('foo.ini.in', 'lib', {'foo': bar})

假設 foo.ini.in 檔案具有以下內容

[meta]
Name=@foo@
Version=1.0
Description=dummy description

[default]
Cflags=-I@prefix@/include
Libs=

產生的檔案將具有以下內容

[meta]
Name=bar
Version=1.0
Description=dummy description

[default]
Cflags=-Iprefix_dir/include
Libs=

並將作為 foo.ini 安裝在 'lib' 子路徑中。

當使用 numpy distutils 進行交叉編譯時,可能需要使用修改過的 npy-pkg-config 檔案。使用預設/產生的檔案將與主機程式庫(即 libnpymath.a)連結。對於交叉編譯,您當然需要與目標程式庫連結,同時使用主機 Python 安裝。

您可以複製出 numpy/_core/lib/npy-pkg-config 目錄,將 pkgdir 值新增至 .ini 檔案,並設定 NPY_PKG_CONFIG_PATH 環境變數以指向具有修改過的 npy-pkg-config 檔案的目錄。

針對交叉編譯修改的範例 npymath.ini

[meta]
Name=npymath
Description=Portable, core math library implementing C99 standard
Version=0.1

[variables]
pkgname=numpy._core
pkgdir=/build/arm-linux-gnueabi/sysroot/usr/lib/python3.7/site-packages/numpy/_core
prefix=${pkgdir}
libdir=${prefix}/lib
includedir=${prefix}/include

[default]
Libs=-L${libdir} -lnpymath
Cflags=-I${includedir}
Requires=mlib

[msvc]
Libs=/LIBPATH:${libdir} npymath.lib
Cflags=/INCLUDE:${includedir}
Requires=mlib
paths(*paths, **kws)[source]#

將 glob 套用至路徑,並在需要時在前面加上 local_path。

將 glob.glob(…) 套用至序列中的每個路徑(如果需要),並在需要時在前面加上 local_path。由於這會在所有來源清單上呼叫,因此允許在擴充模組、程式庫和腳本的來源清單中指定萬用字元,並允許路徑名稱相對於來源目錄。

get_config_cmd()[source]#

傳回 numpy.distutils config 命令實例。

get_build_temp_dir()[source]#

傳回臨時目錄的路徑,應將臨時檔案放置在其中。

have_f77c()[source]#

檢查 Fortran 77 編譯器的可用性。

在來源產生函式內部使用它,以確保 setup 發行實例已初始化。

註解

如果 Fortran 77 編譯器可用,則為 True(因為簡單的 Fortran 77 程式碼能夠成功編譯)。

have_f90c()[source]#

檢查 Fortran 90 編譯器的可用性。

在來源產生函式內部使用它,以確保 setup 發行實例已初始化。

註解

如果 Fortran 90 編譯器可用,則為 True(因為簡單的 Fortran 90 程式碼能夠成功編譯)

get_version(version_file=None, version_variable=None)[source]#

嘗試取得套件的版本字串。

傳回目前套件的版本字串,如果無法偵測到版本資訊,則傳回 None。

註解

此方法掃描名為 __version__.py、<套件名稱>_version.py、version.py 和 __svn_version__.py 的檔案,以尋找字串變數 version、__version__ 和 <套件名稱>_version,直到找到版本號碼。

make_svn_version_py(delete=True)[source]#

將資料函式附加到 data_files 清單,該函式將在目前的套件目錄中產生 __svn_version__.py 檔案。

從 SVN 修訂編號產生套件 __svn_version__.py 檔案,它會在 python 結束後移除,但在執行 sdist 等命令時可用。

註解

如果 __svn_version__.py 之前已存在,則不執行任何動作。

這適用於處理位於 SVN 儲存庫中的來源目錄。

make_config_py(name='__config__')[source]#

產生包含在套件建置期間使用的 system_info 資訊的套件 __config__.py 檔案。

此檔案會安裝到套件安裝目錄。

get_info(*names)[source]#

取得資源資訊。

傳回單一字典中,引數列表中所有名稱的資訊 (來自 system_info.get_info)。

建置可安裝的 C 程式庫#

傳統的 C 程式庫(透過 add_library 安裝)不會被安裝,僅在建置期間使用(它們是靜態連結的)。可安裝的 C 程式庫是純 C 程式庫,不依賴 python C 執行時期環境,且安裝後可供第三方套件使用。若要建置和安裝 C 程式庫,您只需使用方法 add_installed_library 而非 add_library,後者接受相同的引數,但多了一個 install_dir 引數

.. hidden in a comment so as to be included in refguide but not rendered documentation
  >>> import numpy.distutils.misc_util
  >>> config = np.distutils.misc_util.Configuration(None, '', '.')
  >>> with open('foo.c', 'w') as f: pass

>>> config.add_installed_library('foo', sources=['foo.c'], install_dir='lib')

npy-pkg-config 檔案#

為了讓第三方可以使用必要的建置選項,您可以使用 npy-pkg-config 機制,此機制實作於 numpy.distutils 中。此機制基於一個包含所有選項的 .ini 檔案。.ini 檔案與 pkg-config unix 工具使用的 .pc 檔案非常相似

[meta]
Name: foo
Version: 1.0
Description: foo library

[variables]
prefix = /home/user/local
libdir = ${prefix}/lib
includedir = ${prefix}/include

[default]
cflags = -I${includedir}
libs = -L${libdir} -lfoo

一般來說,檔案需要在建置期間產生,因為它需要一些僅在建置時才知道的資訊(例如 prefix)。如果使用 Configuration 方法 add_npy_pkg_config,這大部分是自動完成的。假設我們有一個範本檔案 foo.ini.in 如下

[meta]
Name: foo
Version: @version@
Description: foo library

[variables]
prefix = @prefix@
libdir = ${prefix}/lib
includedir = ${prefix}/include

[default]
cflags = -I${includedir}
libs = -L${libdir} -lfoo

以及 setup.py 中的以下程式碼

>>> config.add_installed_library('foo', sources=['foo.c'], install_dir='lib')
>>> subst = {'version': '1.0'}
>>> config.add_npy_pkg_config('foo.ini.in', 'lib', subst_dict=subst)

這會將檔案 foo.ini 安裝到目錄 package_dir/lib 中,並且 foo.ini 檔案將從 foo.ini.in 產生,其中每個 @version@ 都會被 subst_dict['version'] 取代。字典會自動新增一個額外的 prefix 取代規則,其中包含安裝 prefix(因為這不容易從 setup.py 取得)。

重複使用來自另一個套件的 C 程式庫#

資訊可以從 get_info 函式中輕鬆取得,該函式位於 numpy.distutils.misc_util

>>> info = np.distutils.misc_util.get_info('npymath')
>>> config.add_extension('foo', sources=['foo.c'], extra_info=info)
<numpy.distutils.extension.Extension('foo') at 0x...>

可以將要尋找 .ini 檔案的路徑的額外列表提供給 get_info

轉換 .src 檔案#

NumPy distutils 支援自動轉換名為 <somefile>.src 的原始碼檔案。此功能可用於維護非常相似的程式碼區塊,這些區塊之間僅需進行簡單的變更。在設定的建置階段期間,如果遇到名為 <somefile>.src 的範本檔案,則會從範本建構一個名為 <somefile> 的新檔案,並將其放置在建置目錄中以供使用。支援兩種形式的範本轉換。第一種形式發生在名為 <file>.ext.src 的檔案中,其中 ext 是可識別的 Fortran 副檔名(f、f90、f95、f77、for、ftn、pyf)。第二種形式用於所有其他情況。請參閱 使用範本轉換 .src 檔案