【问题标题】:Module path dependencies模块路径依赖
【发布时间】:2014-05-08 12:00:52
【问题描述】:

让我们假设项目的目录结构如下

<root>
  __init__.py
  helloworld.py
<moduleOne>
  f.txt
  __init__.py
  printfile.py

root 和 moduleOne 是目录

helloworld.py 的内容:

#!/usr/bin/python
import helloworld.printfile
printf()

moduleOne/打印文件的内容

#!/usr/bin/python
f = open('f.txt')

def printf():
    print 'print file'
    print f

if __name__ == '__main__':
   printf()

我的问题:

从 moduleOne/ 执行 printfile 没问题,但是从 root/ 运行 helloworld.py 会发生以下错误:

import moduleOne.printfile
File "/root/moduleOne/printfile.py", line 5, in <module>
 f = open('f.txt')
IOError: [Errno 2] No such file or directory: 'f.txt'

如何在python中解决这个问题?

[已编辑]

我通过“解决方法”(或多或少)解决了这个问题,但仍然有问题:

我的解决方案:

在moduleOne/printfile中

import sys
fname = 'moduloOne/f.txt'

def printf():

    f = open(fname)
    print 'print file'  
    print f

if __name__ == '__main__':

    fname = 'f.txt'
    printf()    

但是……

假设我有一个新目录,从根目录,称为 etc,那么新结构是:

<root>
  __init__.py
  helloworld.py
<moduleOne>
  f.txt
  __init__.py
  printfile.py
<etc>
  f2.txt

现在我需要从 moduleOne/printfile 访问 etc/f2.txt。怎么样?

【问题讨论】:

  • 你试过f = open('moduleOne/f.txt')吗?
  • 我试过这个(现在),从 工作,但从 失败:IOError: [Errno 2] No such file or directory: 'moduleOne/f.txt'
  • 你需要从两个模块访问'f.txt'吗?
  • 是的,实际上我需要从其他模块访问 f.txt(配置文件)。
  • 'f.txt' 在 root 或 moduleOne 中吗?

标签: python


【解决方案1】:

你需要更多的抽象。

  1. 不要在printfile.py 中硬编码文件路径
  2. 不要在printf 函数中访问全局变量。
  3. 接受文件句柄作为printf 函数的参数:

    def printf(file_handle):
        print 'print file'
        print file_handle
    
  4. 在一个确实实际上需要知道f.txt的路径的脚本中(我猜你的情况是helloworld.py),把它放在那里,打开它,然后把它传递给printf

    from moduleOne.printfile import printf
    
    my_f_file = open('/path/to/f.txt')
    printf(my_f_file)
    
  5. 更好的是,从命令行获取文件路径

    import sys
    
    from moduleOne.printfile import printf
    
    input_file_path = sys.argv[1]
    my_f_file = open(input_file_path)
    printf(my_f_file)
    

编辑:你在your Google+ cross-post说:

完整路径有问题,程序将在不同的环境中运行。

如果你试图将你的程序分发给其他用户和机器,你应该查看making a distribution package(见下面的附注3),并使用package_data包含你的配置文件,以及pkgutil或@ 987654337@ 访问配置文件。见How do I use data in package_data from source code?

一些旁注:

  1. 将目录表示为带有尾部斜杠的目录名称,就像 the tree command 的约定:/ 代替 &lt;root&gt;moduleOne/ 代替 &lt;moduleOne&gt;
  2. 您将“模块”与“包”混为一谈。我建议你将moduleOne/ 重命名为packageOne/。带有__init__.py 文件的目录构成一个包。以.py 扩展名结尾的文件是一个模块。模块可以通过物理存在于具有__init__.py 文件的目录中而成为包的一部分。包可以成为其他包的一部分,因为它是具有__init__.py 文件的父目录的物理子目录。
  3. 不幸的是,术语“包”在 Python 中被重载,也可能意味着用于分发和安装的 Python 代码集合。见the Python Packaging Guide glossary

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    • 2019-01-27
    相关资源
    最近更新 更多