Python 3包和脚本中导入的最佳实践

Python 3包和脚本中导入的最佳实践,python,packages,python-import,Python,Packages,Python Import,考虑以下简单的文件夹结构: root Package1 x.py y.py Package2 z.py Examples main.py 现在我们的要求是: x、 py需要导入y.py z、 py需要导入y.py main.py需要导入y.py和z.py 以下是有效的方法: x.py import y def x(): y() def y(): pass import package1.y as y def z(): y.y(

考虑以下简单的文件夹结构:

root
  Package1
    x.py
    y.py
  Package2
    z.py
  Examples
    main.py
现在我们的要求是:

  • x、 py需要导入y.py
  • z、 py需要导入y.py
  • main.py需要导入y.py和z.py
以下是有效的方法:

x.py

import y

def x():
  y()
def y():
  pass
import package1.y as y

def z():
  y.y()
import sys
from os import path
sys.path.append(  path.dirname(  path.dirname( path.abspath(__file__) ) ) )

import package1.y as y
import package2.z as z

y.y()
z.z()
y.py

import y

def x():
  y()
def y():
  pass
import package1.y as y

def z():
  y.y()
import sys
from os import path
sys.path.append(  path.dirname(  path.dirname( path.abspath(__file__) ) ) )

import package1.y as y
import package2.z as z

y.y()
z.z()
z.py

import y

def x():
  y()
def y():
  pass
import package1.y as y

def z():
  y.y()
import sys
from os import path
sys.path.append(  path.dirname(  path.dirname( path.abspath(__file__) ) ) )

import package1.y as y
import package2.z as z

y.y()
z.z()
main.py

import y

def x():
  y()
def y():
  pass
import package1.y as y

def z():
  y.y()
import sys
from os import path
sys.path.append(  path.dirname(  path.dirname( path.abspath(__file__) ) ) )

import package1.y as y
import package2.z as z

y.y()
z.z()
问题:

  • 这是在Python3中设置导入的最佳推荐方法吗
  • 我真的不喜欢在
    main
    中更改
    sys.path
    ,因为它强烈地绑定了关于代码文件中包位置的假设。有什么办法吗
  • 我也真的不喜欢
    导入包1.y中多余的
    as y
    部分。有什么办法吗

  • 一如既往,有两个单独的步骤:

  • 您可以针对包的抽象名称空间编写代码,其中包含
    package1
    package2
    (以及
    sys
    os
    等),但不包含不是包的“示例”(因为
    main.py
    不是模块)
  • 在任何代码运行之前,您都可以适当地设置
    sys.path
    。如果它是您自己的(已卸载)代码,那么就有了,或者您可以编写一个简单的shell脚本包装器来为
    python
    进程设置
  • 所以你的问题的答案是

  • x.py
    中,您可以从中编写
    。导入y
    。(Python2支持此功能,而Python3需要此功能。)
  • 如何设置系统路径取决于您的包装/环境系统。传统的方法是为
    python
    进程设置
    PYTHONPATH
    环境变量,但也有其他方法涉及
    站点
    模块
  • from package1 import y
    通常只命名一次

  • 为了确保我理解,
    root
    不是一个包。您有两个独立的包,分别称为
    Package1
    Package2
    sys.path
    选项不正确,因为这意味着我无法克隆此包的不同副本进行开发。我认为最好的选择是为每个软件包创建
    setup.py
    文件并使其可安装。现在,有人可以安装、安装到virtualenv中,或者在任何测试之外设置自己的路径,以方便他们使用。使只想安装的最终用户更容易…但也使具有一点额外知识的开发人员更容易使用它们。
    x.py
    可以执行
    import.y
    ,但是
    z.py
    在一个完全独立的包中。它需要完整的
    包1.y
    。是的,root不是包。问题是在开发过程中源代码在磁盘上应该是什么样子的?好问题!每个人都有自己的源代码存储库,彼此之间没有任何硬编码关系,这是很常见的。用户将
    pip安装
    他们,开发人员要么
    pip安装--可编辑
    要么
    pip安装--开发
    他们。即使它们由于其他原因位于同一存储库中,它们仍然是独立的python实体。(这当然是我的拙见)第2步注意:“安装您的软件包”是设置
    sys.path
    :)的有效方法@Josh:当然,如果您的环境支持“安装”;很多人使用虚拟环境等等,但我们中的一些人必须将软件包放在非默认位置,并使用外部配置,如。在任何情况下,了解基本机制都是很有用的。不应该有任何安装软件包的需要(用户可以,如果他们愿意的话,但最佳实践不应该要求)。如果您处于开发模式,这一点尤其重要,因为您可能只希望使用自己的版本将包复制到私有文件夹中,而不影响系统级包。在x.y中,为什么要从中编写
    。导入y
    而不是只导入y
    。前者是冗长的,Python3实际上并不需要。@ShitalShah:如果
    x
    y
    在一个包中,那么它肯定是必需的。如果在
    sys.path
    上有目录
    Package1
    (而不是它的父目录),则没有包,但这似乎不是您想要的。