如何使python文件作为脚本可运行并可作为包导入?

2024-10-03 04:28:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我仍在尝试使用python3,但遇到了一个问题:我可以将.py文件作为脚本运行,也可以将其作为模块导入,但不能同时使用这两种方法。在

目录结构

test/
  __init__.py
  test.py
  subwayclock/
    __init__.py
    subwayclock.py
    build/
      gen/
        __init__.py
        gtfs_realtime_pb2.py
        nyct_subway_pb2.py
      __init__.py

在这种情况下测试.py看起来像这样并且可以工作(rawFEED()是subwayclock.subwayclock.subwayclock)公司名称:

^{pr2}$

但是,我不能直接运行脚本,即

python subwayclock/subwayclock.py

因为它给出了以下错误:

Traceback (most recent call last):
  File "subwayclock.py", line 32, in <module>
    from .build.gen.gtfs_realtime_pb2 import FeedMessage
SystemError: Parent module '' not loaded, cannot perform relative import

但是,如果我在subwayclock中修改import语句/地铁时钟.py陈述(即去掉前导“.”):

from subwayclock.subwayclock import FeedMessage

我可以管理地铁时钟.py直接通过命令行编写脚本,完美地调用main函数。在

但是,当我运行原始的测试.py文件时,import语句不再工作,我得到以下错误:

  Traceback (most recent call last):
  File "test.py", line 1, in <module>
        from subwayclock.subwayclock import *
      File "/var/www/test/subwayclock/subwayclock.py", line 32, in <module>
        from build.gen.gtfs_realtime_pb2 import FeedMessage
    ImportError: No module named 'build'

我能让这个脚本独立地运行和导入吗?在


Tags: frompytestimportbuild脚本initline
3条回答

在这种情况下,您可以使用绝对导入而不是相对导入,但根据模块之间的依赖关系,这可能会导致一些奇怪的行为,其中对象和类在技术上被定义了两次(一次在您的__main__脚本中,一次在另一个模块导入您的模块时)

正确的方法是使用setup.py脚本创建一个适当的python包,并使用^{}入口点特性将函数公开为命令行脚本。在

你的项目应该这样组织。在

/subwayclock
    /subwayclock
        __init__.py
        subwayclock.py
        ...
    setup.py

你的设置.py看起来像这样

^{pr2}$

然后你只需安装软件包

$ python setup.py install

(您也可以使用develop模式,这样您仍然可以使用它)

$ python setup.py develop

你就可以运行命令行脚本了

$ subwayclock_script_name

可以使用-m开关和完全限定的包路径从包运行脚本

python -m subwayclock.subwayclock

我将试着描述你,它是如何工作的,同时,也为了帮助你。在


相对导入

首先,python有许多不同的方法可以导入一些。 其中一些是相对导入(from .package import somemodule
圆点意味着我们要从当前包中导入somemodule。这意味着我们应该声明我们的包(当我们导入这个模块时,我们从包中导入它,它有一个名称等)


绝对进口(也许还有另一个名字)

此导入几乎在简单脚本中的任何地方都使用,您必须知道这一点。
示例:

from app import db

其中app是python模块(app.py文件),而{}是中的变量它。如果你想知道更多,read the docs。在



解决方案

我真的不知道怎样才能避免这种情况,但如果我是你,我会这样做:

^{pr2}$

也可以在简单的情况下运行python -m package.module.function,但这不是一个好主意。
或者可以将包目录添加到PYTHONPATH变量中。看到几乎相同问题的good answer。在

相关问题 更多 >