【问题标题】:How to properly package set of callable python scripts or modules如何正确打包一组可调用的 python 脚本或模块
【发布时间】:2020-07-10 17:19:28
【问题描述】:

我已经在网上搜索了很长一段时间,但我似乎无法弄清楚如何为我的最终用户分发我的 python 脚本。

我一直在我的命令行上使用我的脚本使用这个命令python samplemodule.py "args1"

这也是我希望我的用户在他们的命令行中使用它的方式。但我担心的是,某些模块依赖于其他库或模块。

当我的脚本都在项目的根目录中时,它们可以工作,但是当我尝试将它们打包并将它们放在子目录中时,一切都崩溃了。

这方面的一个例子是我现在无法运行我的脚本,因为当我从 data 子目录导入模块时出现错误。

这是我的项目结构。

MyProject
    \formatter
      __init__.py
      __main__.py
      formatter.py
      addfilename.py
      addscrapertype.py
     ...\data
         __init__.py
         helper.py
     csv_formatter.py
     setup.py

csv_formatter.py 文件只是调用 formatter.main 的包装器。

更新:我现在能够生成一个 tar.gz 包,但该包在安装到我的机器上时无法调用。

这是 setup.py:

import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="formatter",
    version="1.0.1",
    author="My Name",
    author_email="sample@email.com",
    description="A package for cleaning and reformatting csv data",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/RhaEL012/Python-Scripts",
    packages=["formatter"],
    include_package_data=True,
    package_data={
    # If any package contains *.txt or *.rst files, include them:
        "": ["*.csv", "*.rst", "*.txt"],
    },
    entry_points={
         "console_scripts": [
            "formatter=formatter.formatter:main"
        ]
    },
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6',
    install_requires=[
        "pandas"
    ]
)

现在,在机器上安装软件包后,我无法调用该模块并导致错误:

Z:\>addfilename "C:\Users\Username\Desktop\Python Scripts\"

更新:我尝试在虚拟环境中安装 setup.py 只是为了查看错误来自何处。

我安装它然后我收到以下错误:FileNotFoundError: [Errno 2] no such file or directory: 'README.md'

我尝试将README.md 包含在MANIFEST.in 中,但仍然没有运气。 所以我试着把它变成一个字符串,看看安装是否会继续。

安装继续进行,但我又遇到了一个错误,提示 package directory 'formatter' does not exist

【问题讨论】:

  • 您可以通过向环境变量 PYTHONPATH 添加正确的路径来解决此问题。 Python 将在此路径列表中查找导入的包,因此请确保其中存在正确的包。
  • 嗨@brunodesthuilliers,我已经按照教程进行了操作,但似乎没有得到我想要的结果。我创建了一个 tar.gz。文件,但一旦我将它安装在我的机器上。它无法识别包上的模块。
  • @BLitE.exe 好吧,我恐怕帮不上什么忙,特别是在 Windows 上 - 但至少你发布了你所做的,希望更有知识的人可以加入 ;-)跨度>
  • 有机会在线查看该项目,或者至少查看__init____main__ 的内容吗?很高兴在安装后看到您当前最终的结构(最简单的方法是至少部分共享源代码,以便我可以自己在本地构建它)。

标签: python python-3.x package pyinstaller


【解决方案1】:

由于我无法查看您的特定文件,因此我将仅解释我通常如何解决此问题。

这是我通常设置命令行界面 (cli) 工具的方式。项目文件夹如下所示:

Projectname
├── modulename
│   ├── __init__.py # this one is empty in this example
│   ├── cli
│   │   ├── __init__.py # this is the __init__.py that I refer to hereafter
│   ├── other_subfolder_with_scripts
├── setup.py

所有功能都在 modulename 文件夹和子文件夹中。 在我的__init__.py 我有:

def main():
    # perform the things that need to be done 
    # also all imports are within the function call
    print('doing the stuff I should be doing')

但我认为您也可以将您想要的内容导入__init__.py 并仍然以我在setup.py 中的方式引用它。 在setup.py 我们有:

import setuptools

setuptools.setup(
    name='modulename',
    version='0.0.0',
    author='author_name',
    packages=setuptools.find_packages(),
    entry_points={
        'console_scripts': ['do_main_thing=modulename.cli:main'] # so this directly refers to a function available in __init__.py
        },
)

现在用pip install "path to where setup.py is"安装包然后如果安装了你可以调用:

do_main_thing
>>> doing the stuff I should be doing

对于我使用的文档:https://setuptools.readthedocs.io/en/latest/

我的建议是从这个开始,慢慢添加你想要的功能。然后一步一步解决你的问题,比如添加一个 README.md 等等。

【讨论】:

    【解决方案2】:

    我不同意另一个答案。您不应在 __init__.py 中运行脚本,而应在 __main__.py 中运行脚本。

    Projectfolder
    ├── formatter
    │   ├── __init__.py
    │   ├── cli
    │   │   ├── __init__.py # Import your class module here
    │   │   ├── __main__.py # Call your class module here, using __name__ == "__main__"
    │   │   ├── your_class_module.py
    ├── setup.py
    

    如果您不想提供自述文件,只需删除该代码并手动输入说明即可。

    我使用https://setuptools.readthedocs.io/en/latest/setuptools.html#find-namespace-packages 而不是手动设置包。

    您现在可以像以前一样运行pip install ./ 来安装您的软件包。

    完成该运行后:python -m formatter.cli arguments。它运行您在 CLI 文件夹(或您所称的任何名称)中创建的 __main__.py 文件。

    关于打包模块的一个重要注意事项是您需要使用相对导入。例如,您将在 __init__.py 中使用 from .your_class_module import YourClassModule。如果要从相邻文件夹中导入某些内容,则需要两个点 from ..helpers import HelperClass

    【讨论】:

      【解决方案3】:

      我不确定这是否有帮助,但通常我使用 wheel 包来打包我的 python 脚本:

      pip install wheel
      python setup.py sdist bdist_wheel
      

      在这两个命令之后,会在“dist”文件夹中创建一个 whl 包,然后您可以将其上传到 PyPi 并从那里下载/安装,或者您可以使用“pip install ${PackageName}.py”离线安装它"

      这是一个有用的用户指南,以防万一我没有解释其他内容:

      https://packaging.python.org/tutorials/packaging-projects/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-06
        • 2018-02-17
        • 1970-01-01
        • 2023-03-19
        • 1970-01-01
        • 2014-07-12
        • 2017-02-23
        • 2018-01-05
        相关资源
        最近更新 更多