我正在分发一个具有以下结构的包:
mymodule:
mymodule/__init__.py
mymodule/code.py
scripts/script1.py
scripts/script2.py
mymodule
的{{1}}子目录包含代码,mymodule
子目录包含应由用户执行的脚本。
在scripts
中描述软件包安装时,我使用:
setup.py
指定脚本的位置。在安装过程中,它们通常会进入某个平台/用户特定的scripts=['myscripts/script1.py']
目录。我在bin
中的代码需要调用脚本。然后找到这些脚本的完整路径的正确方法是什么?理想情况下,它们应该在用户的路径上,所以如果我想从shell中调用它们,我应该可以这样做:
mymodule/mymodule
但我希望通过其绝对路径调用脚本,而不是依赖于os.system('script1.py args')
上的特定于平台的bin目录,如:
PATH
如何做到这一点?感谢。
编辑删除脚本以外的代码对我来说不是一个实用的解决方案。原因是我将作业分配到集群系统,而我通常这样做的方式是这样的:假设你有一组你想要运行的任务。我有一个脚本,它将所有任务作为输入,然后调用另一个脚本,该脚本仅在给定任务上运行。类似的东西:
# get the directory where the scripts reside in current installation
scripts_dir = get_scripts_dir()
script1_path = os.path.join(scripts_dir, "script1.py")
os.system("%s args" %(script1_path))
所以main.py:
for task in tasks:
cmd = "python script.py %s" %(task)
execute_on_system(cmd)
需要知道main.py
的位置,因为它需要是script.py
可执行的命令。
答案 0 :(得分:3)
我认为您应该构建代码,以便不需要从代码中调用脚本。将您需要的代码从脚本移动到包中,然后您可以从脚本和代码中调用此代码。
答案 1 :(得分:1)
我的用例是检查我的脚本安装到的目录是否在用户的路径中,如果没有则发出警告(因为如果用--user安装,它通常不在路径中) 。这是我提出的解决方案:
from setuptools.command.easy_install import easy_install
class my_easy_install( easy_install ):
# Match the call signature of the easy_install version.
def write_script(self, script_name, contents, mode="t", *ignored):
# Run the normal version
easy_install.write_script(self, script_name, contents, mode, *ignored)
# Save the script install directory in the distribution object.
# This is the same thing that is returned by the setup function.
self.distribution.script_install_dir = self.script_dir
...
dist = setup(...,
cmdclass = {'build_ext': my_builder, # I also have one of these.
'easy_install': my_easy_install,
},
)
if dist.script_install_dir not in os.environ['PATH'].split(':'):
# Give a sensible warning message...
我应该指出这是针对setuptools的。如果你使用distutils,那么解决方案是类似的,但略有不同:
from distutils.command.install_scripts import install_scripts
class my_install_scripts( install_scripts ): # For distutils
def run(self):
install_scripts.run(self)
self.distribution.script_install_dir = self.install_dir
dist = setup(...,
cmdclass = {'build_ext': my_builder,
'install_scripts': my_install_scripts,
},
)
答案 2 :(得分:0)
我认为正确的解决方案是
scripts=glob("myscripts/*.py"),