代码之家  ›  专栏  ›  技术社区  ›  Bram Vanroy

也可以作为命令行脚本运行的包的结构

  •  5
  • Bram Vanroy  · 技术社区  · 7 年前

    我已经写了一个包裹 the 'standard' minimal structure . 看起来是这样的:

    my_package/
        my_package/
            __init__.py
        setup.py
    

    __init__.py 包含一个类,因此可以像预期的那样简单地导入和使用。

    python my_package --arg1 "I like bananas."
    

    起初,我只是有一个 if __name__ == '__main__' __init__ 然后哪个会使用 argparse . 这 作品 但它并不漂亮,因为这意味着您可以从命令行这样调用它:

    python my_package/__init__.py --arg1 "I like bananas."
    

    据我所知,这是一个 __main__.py 文件将作为默认脚本在文件夹中执行(类似于 index.html 在网站上存档)。我的想法是简单地导入 __初始值 ,运行argparse并将参数提供给类构造函数。像这样:

    import argparse
    from __init__ import MyClass
    
    parser = argparse.ArgumentParser()
    parser.add_argument("--arg1", help="Some dummy value")
    
    args = parser.parse_args()
    my_class = MyClass(**vars(args))
    my_class.do_stuff()
    


    以上工作 __初始化__ MyClass .__init__ 相反(带一个点)警告消失了,但是代码不再工作了,给了我一个警告 ImportError: attempted relative import with no known parent package .

    1 回复  |  直到 7 年前
        1
  •  5
  •   RunOrVeith    7 年前

    我想向您建议一种不同的结构:

    my_package/
        my_package/
            __init__.py
            cli_scripts.py
        setup.py
    

    让我们假设你的 __init__.py 看起来是这样的(作为旁注,我建议将其中定义的类移动到一个单独的文件中,然后在 __init__ ):

    class Test(object):
    
        def __init__(self, a)
            self.a = a
    
        def __call__(self):
            print(self.a)
    

    cli_scripts.py :

    import argparse
    
    from my_package import Test
    
    
    def parse_args():
        parser = argparse.ArgumentParser()
        parser.add_argument("a", type=int, help="Just an example argument")
        return parser.parse_args()
    
    def demonstration():
        args = parse_args()
        t = Test(a=args.a)
        t()
    

    我现在的建议是利用 console_scripts entry point setup.py

    from setuptools import setup
    
    setup(
        name='testpy',
        version='0.1',
        description='Just an example',
        author='RunOrVeith',
        author_email='xyz@mailinator.com',
        packages=["my_package"],
        entry_points={
            "console_scripts": ["mypkg=my_package.cli_scripts:demonstration"]},
        install_requires=[],
    )
    

    现在当你跑的时候 pip install . 顶层内部 my_package 文件夹中,将安装您的软件包。这个 entry_points setup.py mypkg . 这意味着你现在可以跑步了

    mypkg 5 这会给你打电话 demonstration()

    • 你不需要处理任何问题 __main__ 文件夹
    • 您不需要关心脚本是否可执行,也不需要指定使用 python
    • 您可以在列表中包含任意数量的这些内容 入境点
    • 而不是

    我觉得这很干净。 你可以阅读更多关于 入境点 this blog 如果要使用中指定的代码 __主要__ cli_scripts 方法,你可以看看 this question .