如何使 python 包引用打包的非 python 可执行文件 (.exe); Windows
How to make python package refer to packaged, non-python executable (.exe); Windows
我正在整理一个 Python 包,它使用 Cygwin 可执行文件,但没有安装 Cygwin。这意味着我的包中有一个可执行 (.exe
) 文件和一个库 (.dll
) 文件。我这样做是为了让只使用 Windows 和 Python 的人可以在 Windows 上使用该工具。我是 Python 软件包的新手,非常感谢您的帮助。
主要问题
如何让我的包指向我的包中的可执行文件?例如,这将用于代替 PATH
引用的可执行文件。答案可能在那里,但我在搜索中发现的只是一堆关于如何从 Python 脚本创建可执行文件的信息,这不是我想要的。
Details/My 尝试
该工具是sclite
,一个对语音识别输出进行评分的工具。有关我如何在 Windows 上获得可用工具的信息,请查看下面的 如何安装 SCLITE(用于重现能力) 部分。
这是我如何设置包裹的一个小“玩具”示例。
$ tree package_holder_dir/
package_holder_dir/
├── bbd_package
│ ├── __init__.py
│ ├── non_py_exe_dll
│ │ ├── cygwin1.dll
│ │ └── sclite.exe
│ ├── score
│ │ ├── __init__.py
│ │ └── run_sclite.py
│ └── score_transcript.py
├── MANIFEST.in
├── README.txt
└── setup.py
3 directories, 9 files
我的第一个猜测是 sclite.exe
应该放在 MANIFEST.in
文件中。
# @file MANIFEST.in
include ./README.txt
include ./bbd_package/non_py_exe_dll/sclite.exe
include ./bbd_package/non_py_exe_dll/cygwin1.dll
我也试过把它们放在setup.py
我的setup.py
如下
#!/usr/bin/env/python3
# -*- coding: utf-8 -*-
# @file setup.py
import setuptools
from distutils.core import setup
with open ("README.txt", "r") as fh:
long_description = fh.read()
setup(
name='bbd_package',
url='user@host.com',
author='bballdave025',
author_email='not.likely@idontwantspam.com',
packages=setuptools.find_packages(),
#data_files=[('lib', ['./non_py_exe_dll/cygwin1.dll']),
# './non_py_exe_dll/sclite.exe'],
version='0.0.1',
description="Example for SO",
long_description=long_description,
include_package_data=True
) ##endof: setup
注意 this source (archived) 因为我使用 data_files
作为 DLL
的位置。但是,当我在别处安装发行版时找不到这些文件。这就是他们在这里被注释掉的原因。
使用MANIFEST.in
似乎可行,但后来我不得不使用相对路径来访问可执行文件。在另一个目录中尝试 import bbd_package
时,这将不起作用。
让我试着用我的两个 Python 文件来说明:
score_transcript.py
只是调用 run_sclite.py
.
#!/usr/env/bin python3
# -*- coding: utf-8 -*-
# @file run_sclite.py
import os, sys, subprocess
def run_sclite(hyp, ref):
subprocess.call(['../non_py_exe_dll/sclite.exe', '-h', hyp, '-r', ref, '-i', 'rm', \
'-o', 'all snt'])
我可以在我的系统上安装它:
C:\toy_executable_example\package_holder_dir>pip install .
那么如果我碰巧在 run_sclite.py
的目录中
C:\toy_executable_example\package_holder_dir\bbd_package\score>python
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import bbd_package.score.run_sclite
>>> bbd_package.score.run_sclite.run_sclite('a.hyp', 'a.ref')
sclite Version: 2.10, SCTK Version: 1.3
...output that shows it works...
>>>
但是,从任何其他目录,没有骰子。
C:\Users\me>python
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit
(AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import bbd_package.score.run_sclite
>>> bbd_package.score.run_sclite.run_sclite('a.hyp', 'a.ref')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\dblack\AppData\Local\Programs\Python\Python36\lib\site-packages\bbd_package\score\run_sclite.py", line 9, in run_sclite
'-o', 'all snt'])
File "C:\Users\dblack\AppData\Local\Programs\Python\Python36\lib\subprocess.py", line 267, in call
with Popen(*popenargs, **kwargs) as p:
File "C:\Users\dblack\AppData\Local\Programs\Python\Python36\lib\subprocess.py", line 709, in __init__
restore_signals, start_new_session)
File "C:\Users\dblack\AppData\Local\Programs\Python\Python36\lib\subprocess.py", line 997, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
>>>
如何告诉 Python 在我的包中查找可执行文件?
系统详细信息
此信息取自 运行 systeminfo
来自 Window 的命令提示符。
OS Name: Microsoft Windows 10 Enterprise
OS Version: 10.0.15063 N/A Build 15063
OS Manufacturer: Microsoft Corporation
OS Configuration: Member Workstation
OS Build Type: Multiprocessor Free
如何安装 SCLITE(用于重现能力)
我在安装说明(使用 Cygwin)中加入了 link ,请查找我的评论。以下是没有解释的命令
$ cd
$ git clone https://github.com/kaldi-asr/kaldi.git
$ cd kaldi/tools
$ extras/check_dependencies.sh
$ make -j $(nproc --all)
$ cp -R sctk-2.4.10 ~/
$ cd
$ rm -rf kaldi
$ cd sctk-2.4.10/
$ cp $HOME/.bashrc "${HOME}/.bashrc.$(date +%Y%m%d-%H%M%S).bak"
$ echo -e "\n\n## Allow access to sclite, rfilter, etc" >> $HOME/.bashrc
$ echo 'export PATH='"$(pwd)/bin"':$PATH' >> $HOME/.bashrc
$ source ~/.bashrc
我还包括 link (archived) 以“更快”的说明和有关 EXE
和 DLL
文件的信息。这都要感谢@benreaves
Easier (but even uglier) workaround, which I gave to an intern who did
some Word Error Rate calculations for me:
On my laptop with Cygwin installed, I create sclite.exe
using my
cp src/*/*.c . ; make all
workaround from my previous message
I create a zip file containing sclite.exe
and cygwin1.dll
from my
laptop's c:/cygwin/bin/
folder
Email that zip file to her, and she copies both files in a single new
folder on her laptop and set PATH=.;%PATH%
我没有设置 PATH
,因为我希望它可以分发。
This worked just fine on her laptop running Windows 7, and she didn't
need Cygwin or any other NIST software on her laptop.
-Ben
我终于让它工作了。我修补在一起的来源如下。基本答案是我使用 __file__
变量找到调用打包模块的目录,然后使用相对路径到达我的可执行文件。我对这个解决方案不是很满意(here {archived} 在某些情况下它不起作用),但它现在可以完成工作。
细节
MANIFEST.in
文件保持不变:
# @file MANIFEST.in
# @author bballdave025
include ./README.txt
include ./bbd_package/non_py_exe_dll/sclite.exe
include ./bbd_package/non_py_exe_dll/cygwin1.dll
但是,我需要将以下内容添加到 exe
-运行 代码中。这是在run_sclite.py
from pathlib import Path
#...
path_to_here = os.path.dirname(os.path.abspath(__file__))
path_to_pkg_root = Path(path_to_here).resolve().parents[1]
path_to_exe = os.path.join(path_to_pkg_root, 'non_py_exe_dll')
#...
请注意 Python 版本 >= 3.4 是 pathlib
所必需的
这是整个 (run_sclite.py
) 文件:
#!/usr/env/bin python3
# -*- coding: utf-8 -*-
# @file run_sclite.py
# @author bballdave025
import os, sys, subprocess
from pathlib import Path
def run_sclite(hyp, ref):
path_to_here = os.path.dirname(os.path.abspath(__file__))
path_to_pkg_root = Path(path_to_here).resolve().parents[1]
path_to_exe = os.path.join(path_to_pkg_root, 'non_py_exe_dll')
subprocess.call([os.path.join(path_to_exe, 'sclite.exe'), '-h', hyp, '-r', ref, \
'-i', 'rm', '-o', 'all snt'])
##endof: run_sclite(hyp, ref)
来源
Mouse vs. Python, with clarification on when this solution won't work and other alternatives. (archived)
(archived;寻找“使用 os.path”)。
最终让我得到答案的是什么:Python Packaging Tutorial . Look at the 'Note:'. (archived)
我正在整理一个 Python 包,它使用 Cygwin 可执行文件,但没有安装 Cygwin。这意味着我的包中有一个可执行 (.exe
) 文件和一个库 (.dll
) 文件。我这样做是为了让只使用 Windows 和 Python 的人可以在 Windows 上使用该工具。我是 Python 软件包的新手,非常感谢您的帮助。
主要问题
如何让我的包指向我的包中的可执行文件?例如,这将用于代替 PATH
引用的可执行文件。答案可能在那里,但我在搜索中发现的只是一堆关于如何从 Python 脚本创建可执行文件的信息,这不是我想要的。
Details/My 尝试
该工具是sclite
,一个对语音识别输出进行评分的工具。有关我如何在 Windows 上获得可用工具的信息,请查看下面的 如何安装 SCLITE(用于重现能力) 部分。
这是我如何设置包裹的一个小“玩具”示例。
$ tree package_holder_dir/
package_holder_dir/
├── bbd_package
│ ├── __init__.py
│ ├── non_py_exe_dll
│ │ ├── cygwin1.dll
│ │ └── sclite.exe
│ ├── score
│ │ ├── __init__.py
│ │ └── run_sclite.py
│ └── score_transcript.py
├── MANIFEST.in
├── README.txt
└── setup.py
3 directories, 9 files
我的第一个猜测是 sclite.exe
应该放在 MANIFEST.in
文件中。
# @file MANIFEST.in
include ./README.txt
include ./bbd_package/non_py_exe_dll/sclite.exe
include ./bbd_package/non_py_exe_dll/cygwin1.dll
我也试过把它们放在setup.py
我的setup.py
如下
#!/usr/bin/env/python3
# -*- coding: utf-8 -*-
# @file setup.py
import setuptools
from distutils.core import setup
with open ("README.txt", "r") as fh:
long_description = fh.read()
setup(
name='bbd_package',
url='user@host.com',
author='bballdave025',
author_email='not.likely@idontwantspam.com',
packages=setuptools.find_packages(),
#data_files=[('lib', ['./non_py_exe_dll/cygwin1.dll']),
# './non_py_exe_dll/sclite.exe'],
version='0.0.1',
description="Example for SO",
long_description=long_description,
include_package_data=True
) ##endof: setup
注意 this source (archived) 因为我使用 data_files
作为 DLL
的位置。但是,当我在别处安装发行版时找不到这些文件。这就是他们在这里被注释掉的原因。
使用MANIFEST.in
似乎可行,但后来我不得不使用相对路径来访问可执行文件。在另一个目录中尝试 import bbd_package
时,这将不起作用。
让我试着用我的两个 Python 文件来说明:
score_transcript.py
只是调用 run_sclite.py
.
#!/usr/env/bin python3
# -*- coding: utf-8 -*-
# @file run_sclite.py
import os, sys, subprocess
def run_sclite(hyp, ref):
subprocess.call(['../non_py_exe_dll/sclite.exe', '-h', hyp, '-r', ref, '-i', 'rm', \
'-o', 'all snt'])
我可以在我的系统上安装它:
C:\toy_executable_example\package_holder_dir>pip install .
那么如果我碰巧在 run_sclite.py
C:\toy_executable_example\package_holder_dir\bbd_package\score>python
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import bbd_package.score.run_sclite
>>> bbd_package.score.run_sclite.run_sclite('a.hyp', 'a.ref')
sclite Version: 2.10, SCTK Version: 1.3
...output that shows it works...
>>>
但是,从任何其他目录,没有骰子。
C:\Users\me>python
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit
(AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import bbd_package.score.run_sclite
>>> bbd_package.score.run_sclite.run_sclite('a.hyp', 'a.ref')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\dblack\AppData\Local\Programs\Python\Python36\lib\site-packages\bbd_package\score\run_sclite.py", line 9, in run_sclite
'-o', 'all snt'])
File "C:\Users\dblack\AppData\Local\Programs\Python\Python36\lib\subprocess.py", line 267, in call
with Popen(*popenargs, **kwargs) as p:
File "C:\Users\dblack\AppData\Local\Programs\Python\Python36\lib\subprocess.py", line 709, in __init__
restore_signals, start_new_session)
File "C:\Users\dblack\AppData\Local\Programs\Python\Python36\lib\subprocess.py", line 997, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
>>>
如何告诉 Python 在我的包中查找可执行文件?
系统详细信息
此信息取自 运行 systeminfo
来自 Window 的命令提示符。
OS Name: Microsoft Windows 10 Enterprise
OS Version: 10.0.15063 N/A Build 15063
OS Manufacturer: Microsoft Corporation
OS Configuration: Member Workstation
OS Build Type: Multiprocessor Free
如何安装 SCLITE(用于重现能力)
我在安装说明(使用 Cygwin)中加入了 link
$ cd
$ git clone https://github.com/kaldi-asr/kaldi.git
$ cd kaldi/tools
$ extras/check_dependencies.sh
$ make -j $(nproc --all)
$ cp -R sctk-2.4.10 ~/
$ cd
$ rm -rf kaldi
$ cd sctk-2.4.10/
$ cp $HOME/.bashrc "${HOME}/.bashrc.$(date +%Y%m%d-%H%M%S).bak"
$ echo -e "\n\n## Allow access to sclite, rfilter, etc" >> $HOME/.bashrc
$ echo 'export PATH='"$(pwd)/bin"':$PATH' >> $HOME/.bashrc
$ source ~/.bashrc
我还包括 link (archived) 以“更快”的说明和有关 EXE
和 DLL
文件的信息。这都要感谢@benreaves
Easier (but even uglier) workaround, which I gave to an intern who did some Word Error Rate calculations for me:
On my laptop with Cygwin installed, I create
sclite.exe
using mycp src/*/*.c . ; make all
workaround from my previous message
I create a zip file containing
sclite.exe
andcygwin1.dll
from my laptop'sc:/cygwin/bin/
folderEmail that zip file to her, and she copies both files in a single new folder on her laptop
andset PATH=.;%PATH%
我没有设置 PATH
,因为我希望它可以分发。
This worked just fine on her laptop running Windows 7, and she didn't need Cygwin or any other NIST software on her laptop.
-Ben
我终于让它工作了。我修补在一起的来源如下。基本答案是我使用 __file__
变量找到调用打包模块的目录,然后使用相对路径到达我的可执行文件。我对这个解决方案不是很满意(here {archived} 在某些情况下它不起作用),但它现在可以完成工作。
细节
MANIFEST.in
文件保持不变:
# @file MANIFEST.in
# @author bballdave025
include ./README.txt
include ./bbd_package/non_py_exe_dll/sclite.exe
include ./bbd_package/non_py_exe_dll/cygwin1.dll
但是,我需要将以下内容添加到 exe
-运行 代码中。这是在run_sclite.py
from pathlib import Path
#...
path_to_here = os.path.dirname(os.path.abspath(__file__))
path_to_pkg_root = Path(path_to_here).resolve().parents[1]
path_to_exe = os.path.join(path_to_pkg_root, 'non_py_exe_dll')
#...
请注意 Python 版本 >= 3.4 是 pathlib
这是整个 (run_sclite.py
) 文件:
#!/usr/env/bin python3
# -*- coding: utf-8 -*-
# @file run_sclite.py
# @author bballdave025
import os, sys, subprocess
from pathlib import Path
def run_sclite(hyp, ref):
path_to_here = os.path.dirname(os.path.abspath(__file__))
path_to_pkg_root = Path(path_to_here).resolve().parents[1]
path_to_exe = os.path.join(path_to_pkg_root, 'non_py_exe_dll')
subprocess.call([os.path.join(path_to_exe, 'sclite.exe'), '-h', hyp, '-r', ref, \
'-i', 'rm', '-o', 'all snt'])
##endof: run_sclite(hyp, ref)
来源
Mouse vs. Python, with clarification on when this solution won't work and other alternatives. (archived)
最终让我得到答案的是什么:Python Packaging Tutorial . Look at the 'Note:'. (archived)