Python 获取setuputils包中的入口点脚本文件位置?

Python 获取setuputils包中的入口点脚本文件位置?,python,setuptools,Python,Setuptools,因此,我在setup.py[控制台脚本]部分中定义了一个入口点。该命令已正确安装且运行良好,但我需要一种通过编程找到脚本路径的方法(例如,在windows上,它类似于C:/my/virtual/env/scripts/my_console_script.exe)。我需要它,这样我就可以将该脚本路径作为参数传递给其他命令,而不管包安装在哪里。Setuputils提供了pkg_资源,但这似乎没有公开任何实际获取原始安装路径的方法,只有可加载的对象 编辑:为了使用例变得简单,这里是设置 我有一个插件驱

因此,我在setup.py[控制台脚本]部分中定义了一个入口点。该命令已正确安装且运行良好,但我需要一种通过编程找到脚本路径的方法(例如,在windows上,它类似于C:/my/virtual/env/scripts/my_console_script.exe)。我需要它,这样我就可以将该脚本路径作为参数传递给其他命令,而不管包安装在哪里。Setuputils提供了
pkg_资源
,但这似乎没有公开任何实际获取原始安装路径的方法,只有可加载的对象

编辑:为了使用例变得简单,这里是设置


我有一个插件驱动的应用程序,可以与各种本地服务进行通信。其中一个插件连接到NMS包的警报接口。此警报包将警报发送给任意处理程序的唯一方法是调用脚本-要执行的路径(本例中为console_脚本入口点)注册为完整路径-这是我需要获取的路径。

您在入口点脚本中尝试过`os.path.abspath(u文件_u_u')吗?它将返回您的入口点绝对路径

或者从
distutils.spawn
调用
find\u executable


导入distutils.spawn
distutils.spawn.find\u可执行文件(“可执行文件”)

您可以按如下方式获取站点包目录的路径:

from distutils.sysconfig import get_python_lib
get_python_lib()
import os
scriptPath = os.path.realpath(os.path.join(get_python_lib(), '../my/relative/path/script.exe'))
如果脚本与该路径相对,则可以在站点包中或在目录上,然后将相对路径与站点包路径连接,如下所示:

from distutils.sysconfig import get_python_lib
get_python_lib()
import os
scriptPath = os.path.realpath(os.path.join(get_python_lib(), '../my/relative/path/script.exe'))
您可以尝试的另一个技巧是导入关联的模块,然后查看其文件参数。然后,如果您知道到该文件的相对路径,则可以使用与上述示例相同的方法查找脚本。在命令行界面上尝试

import django
django.__file__
/usr/lib/python2.6/site packages/django/init.pyc

modulePath = os.path.split(django.__file__)[0]
scriptPath = os.path.realpath(os.path.join(modulePath, '../my/relative/path/script.exe'))

上述建议正确吗?

好吧,您可以将形式为
--install option=“--install scripts=/usr/local/bin”
的选项传递到
pip
,然后自己设置路径。但我理解为什么您可能不想在跨平台项目中硬编码

因此,我们只需要找出实际使用的目录
setuptools
。不幸的是,路径是在一组实际安装代码的中间确定的,而不是在我们可以调用的单独函数中。 因此,下一步是编写一个自定义安装命令来观察并保存路径。(就此而言,您还可以将
self.install_scripts
设置到此自定义安装程序类中您选择的目录,从而将该配置保留在一个位置(软件包)而不是软件包和要设置的命令行arg中…)

例如:

从设置工具导入设置
从setuptools.command.install导入安装
从distutils.command.build\u py导入build\u py
导入操作系统
类InstallReadsScriptDir(安装):
def运行(自):
self.distribution.\x\u script\u dir=self.install\u scripts
安装。运行(自我)
类BuildConfiguresScriptDir(生成):
def运行(自):
构建副本运行(自我)
如果self.dry_运行:
返回
script_dir=self.distribution.\x_script_dir#todo:检查是否存在
target=os.path.join(self.build_lib,'mypackage','scriptdir.py')
打开(目标“w”)作为输出文件:
outfile.write('path=”““{}”“”””。格式(script_dir))
设置(
name=“MyPackage”,
version='0.0.1',
packages=['mypackage'],
入口点={
“控制台脚本”:[
'footest=mypackage:main',
],
},
cmdclass={
“安装”:InstallReadsScriptDir,
“build_py”:BuildConfiguresScriptDir,
},
)
可能的反对意见:

  • 有些人不喜欢任何形式的代码生成。在本例中,它更像是配置,尽管将其放在包中的
    .py
    中可以方便地从Python代码的任何位置获取

  • 从表面上看,这看起来有点像黑客。但是,
    setuptools
    是专门为允许自定义命令类而设计的。这里没有任何东西是真正访问私有的,除了可能使用
    分布
    对象传递的值,该对象只是为了避免
    全局

  • 仅获取目录,而不是可执行文件名。不过,根据入口点配置,您应该知道名称。获取名称需要调用入口点规范的解析方法并生成更多代码

  • 如果你在没有安装的情况下进行构建,它将需要一些错误修复<代码>sdist是安全的

  • develope
    是可能的,但需要另一个命令类<代码>安装不会被调用,只有在设置
    使用_2to3
    时才会调用
    生成
    。自定义的
    develope
    命令可以获取路径,如
    install
    示例中所示,但路径为
    self.script\u dir
    。从这里开始,您必须决定是否愿意将文件写入源目录,该目录位于
    self.egg_路径
    ——因为它稍后将被
    install
    获取,尽管它应该是同一个文件(而且build命令将覆盖该文件)

附录

这一闪而过的见解可能更加优雅,因为它不需要将路径保存到任何地方,但仍然可以获得setuptools使用的实际路径,尽管它假定安装后没有更改任何配置

从setuptools导入分发
从setuptools.command.install导入安装
仅类GetScriptPath(安装):
def运行(自):
#不按设计调用install.run()
self.distribution.install\u scripts=self.install\u scripts
def get_setuptools_script_dir():
距离