【问题标题】:Python running a script both from inside and outside the packagePython 从包的内部和外部运行脚本
【发布时间】:2020-07-11 10:53:22
【问题描述】:

继续寻求真正理解 Python 3.7 中的模块和包,这是一个我无法理解的简化场景:

./modtest/test1.py

from test2 import C, y

def x(i):
    print(i)
    a = C()
    y(i)

x(1000)

./modtest/test2.py:

def y(i):
    print(i)

class C(object):
    def __init__(self):
        print("C")
        pass

./testmodtest.py(普通包外)

import modtest.test1
test1(1)

从 pwd = ./ 运行 testmodtest 时出现错误,没有从 test1.py 生成名为“test2”的模块。

当 pwd = ./modtest 时我可以运行 test2

  1. 我做错了什么?
  2. 是否可以编写一个模块(例如 testmodtest.py),使其可以在模块内部和外部运行?

【问题讨论】:

    标签: python-3.7


    【解决方案1】:

    这里有两个问题:

    • test1.py:
      在 import 语句中使用裸模块名称时,Python 会查找该模块 in three places:(1) 当前工作目录,(2) PYTHONPATH 中的目录,以及 (3) 默认包目录(例如 @ 987654328@)。这就是当test2.py 不在这些地方时from test2 import ... 不起作用的原因。但是,当您的模块在一个公共包中时,它们可以使用relative imports 相互导入。因此,以下内容有效,因为点 . 告诉 Python 相对于包含 test1.py 的包查找 test2
      from .test2 import C, y
      
      但是,这仅在 test1.py 未作为脚本运行(即它仅由另一个脚本导入)时有效。
    • testmodtest.py:
      test1(1) 不起作用,因为您已将 test1 导入为 modtest.test1。此外,test1 不可调用,因为它是一个模块——我假设您打算调用 test1.x,它是一个函数。因此,以下任一方法都可以:
      import modtest.test1
      modtest.test1.x(1)
      
      from modtest import test1
      test1.x(1)
      

    另一种可能性是安装您的modtest 包(这基本上意味着将其复制到默认包目录),例如通过创建setup.py 脚本和installing it using pip。如果这样做,您可以从任何工作目录执行 import modtest.test2,并且由于您不再使用相对导入,您还可以将包中的所有模块作为脚本运行(例如 python modtest/test1.py)。

    【讨论】:

      猜你喜欢
      • 2015-10-01
      • 2018-08-14
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-14
      • 1970-01-01
      • 2021-06-21
      相关资源
      最近更新 更多