处理变化路径的会计问题
关于另一个问题,如果路径可能会改变,你该怎么处理呢?比如说,如果一个程序要调用和它在同一个文件夹里的文件,你可以在类Unix系统中直接用路径“.\\foo.py”。但是,Windows系统似乎更喜欢把路径写死,比如“C:\\Python_project\\foo.py”。
如果路径改变了会发生什么呢?比如说,文件可能不在C盘,而是在一个U盘或者外接硬盘上,这样驱动器的字母就可能会变。虽然文件仍然在和程序同一个文件夹里,但代码里的驱动器字母就不匹配了。
我希望这个程序能在不同的平台上都能用,但我想我可能需要用到os.name或者其他什么方法来判断该用哪个路径代码块。
4 个回答
你说的“调用一个文件...foo.py”具体指的是什么呢?
是指导入吗?如果是的话,文件的路径完全在你的程序之外。你需要在命令行设置一个叫做
PYTHONPATH
的环境变量,可以设置为.
或者c:\
,具体看你的系统。比如,你可以写一个两行的命令脚本来设置这个环境变量,然后运行Python。在Windows系统下
SET PYTHONPATH=C:\path\to\library python myapp.py
在Linux系统下
export PYTHONPATH=./relative/path python myapp.py
是指执行文件吗?建议你使用导入的方式。
是指读取和评估吗?同样建议使用导入的方式。
如果设置 PYTHONPATH
太复杂了,那就把你的模块放到Python的lib/site-packages目录下,这样它会默认被加入到 PYTHONPATH
中。
如果你的文件总是在和你的程序同一个文件夹里,那么:
def _isInProductionMode():
""" returns True when running the exe,
False when running from a script, ie development mode.
"""
return (hasattr(sys, "frozen") or # new py2exe
hasattr(sys, "importers") # old py2exe
or imp.is_frozen("__main__")) #tools/freeze
def _getAppDir():
""" returns the directory name of the script or the directory
name of the exe
"""
if _isInProductionMode():
return os.path.dirname(sys.executable)
return os.path.dirname(__file__)
这样应该可以正常工作。此外,我自己在做应用的时候用过py2exe,但没有用其他的exe转换工具测试过。
简单来说:你需要根据环境来确定绝对路径。
你其实需要一些提示。有很多运行时和环境的信息可以从标准库的不同地方获取(这些信息在我想在Windows上部署应用时非常有用)。
首先,来看看一些基本的内容:
os.path
- 这是一个标准库模块,提供了很多跨平台的路径处理功能。它是你最好的朋友。我曾在一本书中看到过“跟着os.path走”。__file__
- 当前模块的位置。sys.executable
- 正在运行的Python的位置。
现在,你可以从这三个来源获取你想要的任何信息。os.path
中的函数会帮助你在文件树中导航:
os.path.join('path1', 'path2')
- 以跨平台的方式连接路径片段。os.path.expanduser('a_path')
- 在用户的主目录中找到路径a_path
。os.path.abspath('a_path')
- 将相对路径转换为绝对路径。os.path.dirname('a_path')
- 获取路径所在的目录。- 还有很多其他功能……
所以,结合这些内容,比如:
# script1.py
# Get the path to the script2.py in the same directory
import os
this_script_path = os.path.abspath(__file__)
this_dir_path = os.path.dirname(this_script_path)
script2_path = os.path.join(this_dir_path, 'script2.py')
print script2_path
然后运行它:
ali@work:~/tmp$ python script1.py
/home/ali/tmp/script2.py
现在针对你的具体情况,似乎你对“工作目录”和“脚本所在目录”的概念有些混淆。这两者可以是相同的,但也可以不同。例如,“工作目录”是可以改变的,因此使用它的函数有时能找到所需的内容,有时却找不到。subprocess.Popen
就是一个例子。
如果你总是使用绝对路径,就不会遇到工作目录的问题。