[分享]关于Python当前路径

142 views
Skip to first unread message

Long

unread,
Feb 22, 2009, 7:23:24 AM2/22/09
to python-cn`CPyUG`华蟒用户组

在写程序的过程中经常会使用到当前路径,因为当前路径使用起来比较方便,只需要持有文件名就可以拿的到该文件的绝对完全路径,这样程序就可以部署在
任何文件目录下。不过,当前路径可是个比较危险的东西,一不留神就会被他骗到,经常也会遇到不少同学询问与当前路径、相对路径、绝对路径的问题。

我就是一个使用当前路径的受害者,而且被困扰了2次,不过最后终于还是找出了原因所在,下面将其与大家分享一下。第一次是用Python写了一个备
份程序,程序主要由3个文件组成:backup.py、config.ini和backup.log,config.ini主要用于设置备份任务的各种
参数,backup.py是通过当前路径的方式来读取config.ini的设置,该程序在Windows和Linux下测试都完全正常,但是在
Linux下通过cron来部署计划任务的时候出现了问题,程序怎么也不能自动运行,当时因为某些原因没有仔细去查原因到底出在什么地方。第二次是我们
要用Python写一个自动更新的程序,它也是由一个主程序去读取一个配置文件来查找服务器的相关信息。该程序在测试时也没有问题,但是通过
py2exe打包成exe并通过Windows的计划任务来部署测试的时候发现程序并没有运行成功,当时非常奇怪,因为不知道问题出现在了什么地方,一
点头绪都没有,然后就是漫长的调试过程,最终发现问题出在读取config.ini这个文件上。通过打印发现当前路径是C:\Windows
\system32,这才想到当前路径是当前的工作路径,并不是当前执行程序文件的路径。

问题找到了,剩下的就是解决问题了。Python下有2个方式是与获取当前路径相关的,一个是os.getcwd(),另外一个是sys.path
[0]。os.getcwd()实际上就是获取当前工作路径(current working directory),而sys.path[0]是当前
运行的脚本文件所在的目录(the directory containing the script that was used to
invoke the Python interpreter)。很显然os.getcwd()不适合,我们只能从sys.path[0]下手,因为他
的doc解释好像正好是我的那两个程序所需要的,然后兴奋的试了一下,改完程序:os.path.join(sys.path[0],
'config.ini'),直接运行程序测试,没有问题。然后打包成exe,配置计划任务后,结果运行失败!没辙了,再打印一下路径看看,发现
sys.path[0]返回的值并不是想象中的那样是一个目录,而是那个可执行文件:E:\test\updater.exe。

问题出来了,sys.path[0]在Python脚本文件中返回的是文件夹的路径E:\test(脚本路径为E:\test
\updater.py),而通过py2exe打包后的exe文件返回的却是该exe的路径E:\test\updater.exe(exe程序路径为
E:\test\updater.exe),为了兼容这两种方式写了一个函数用于获取当前路径:

def getpwd():
pwd = sys.path[0]
if os.path.isfile(pwd):
pwd = os.path.dirname(pwd)
return pwd

至此,问题解决。

刘鑫

unread,
Feb 22, 2009, 7:30:15 AM2/22/09
to pyth...@googlegroups.com
所谓细节决定成就,支持你的分享:)。

2009/2/22 Long <qujinl...@gmail.com>





--
杀人放火金腰带,补路修桥无尸骸。

……

劉鑫
March.Liu

ubunoon

unread,
Feb 22, 2009, 7:44:39 AM2/22/09
to python-cn
linux 下的Python并不会把当前路径放到运行环境中,还是需要自己去获取的。
Windows下就不一样了!
 
 
2009-02-22

ubunoon

发件人: Long
发送时间: 2009-02-22  20:23:24
收件人: python-cn`CPyUG`华蟒用户组
抄送:
主题: [CPyUG:79322] [分享]关于Python当前路径

limodou

unread,
Feb 22, 2009, 7:45:30 AM2/22/09
to pyth...@googlegroups.com
2009/2/22 Long <qujinl...@gmail.com>:

上面的解决说实在的,感觉有问题:

1. config.ini所在的目录应该是运行目录,而不是当前目录。当前目录有可能随时在变,而运行目录则与程序所在的位置有关。
2. sys.path是Python导入模块时搜索的目录,与当前目录无关。在windows下会自动将运行所在的目录加入sys.path,在linux可能就不同的。不知道你在linux下试过吗?

其实你的问题应该是:config.ini与执行文件是在一个目录下或是根据执行文件可以找到config.ini文件。因此只要找到执行文件所在的目录就可以找到config.ini了。并不需要当前目录。应该是使用

os.path.dirname(sys.argv[0])

当运行时sys.argv[0]就是你执行文件的命令行,通过os.path.dirname()可以得到它的目录。它可以是相对路径也可以是绝对路径。

另外如果你是想找导入某个模块相关的文件,可以在导入模块后使用mod.__path__[0]找到它的路径,或os.path.dirname(mod.__file__)找到路径。


--
I like python!
UliPad <<The Python Editor>>: http://code.google.com/p/ulipad/
UliWeb <<simple web framework>>: http://uliwebproject.appspot.com
My Blog: http://hi.baidu.com/limodou

ubunoon

unread,
Feb 22, 2009, 7:50:30 AM2/22/09
to python-cn
 
 
 
2009-02-22

ubunoon

发件人: limodou
发送时间: 2009-02-22  20:45:30
收件人: python-cn
抄送:
主题: [CPyUG:79326] Re: [分享]关于Python当前路径
linux下确实是不一样的,我还记得用uliweb在linux下测试的时候出现过一次问题,后来才找到是运行目录不合适的问题。

Jiahua Huang

unread,
Feb 22, 2009, 7:53:08 AM2/22/09
to pyth...@googlegroups.com
2009/2/22 Long <qujinl...@gmail.com>:

>
> 在写程序的过程中经常会使用到当前路径,因为当前路径使用起来比较方便,只需要持有文件名就可以拿的到该文件的绝对完全路径,这样程序就可以部署在
> 任何文件目录下。不过,当前路径可是个比较危险的东西,一不留神就会被他骗到,经常也会遇到不少同学询问与当前路径、相对路径、绝对路径的问题。
>

问题还是在于你们用工作目录作为执行目录了,
又将执行目录视为"当前路径"。

你在命令行下执行当前目录里的 python 程序时,
这几个目录都是一样的,所以也就忽视了他们的差别。

另外, Windows 下的程序快捷方式,通常都加了相同的工作路径(属性里的"起始位置")
以致有人说"Linux 下不一样"之类。

腾讯出的 Linux QQ 同样有类似的问题,以致腾讯的人得用个脚本先 cd 到程序目录,再来执行

flya flya

unread,
Feb 22, 2009, 8:12:29 AM2/22/09
to pyth...@googlegroups.com
这确实是个问题,似乎mod.__file__比较保险,我一直这样用,但是不知道PY2EXE捆绑之后还行不行了。

linux下快捷方式不能设置"起始位置"确实不太方便,比如我想把python的html格式的document在桌面上建立一个快捷方式,就不行,链接地址都不对,只能先cd到目录下。

2009/2/22 Jiahua Huang <jhuang...@gmail.com>:

--
http://www.flyaflya.com

limodou

unread,
Feb 22, 2009, 8:30:17 AM2/22/09
to pyth...@googlegroups.com
2009/2/22 flya flya <flya...@gmail.com>:

> 这确实是个问题,似乎mod.__file__比较保险,我一直这样用,但是不知道PY2EXE捆绑之后还行不行了。
>
> linux下快捷方式不能设置"起始位置"确实不太方便,比如我想把python的html格式的document在桌面上建立一个快捷方式,就不行,链接地址都不对,只能先cd到目录下。
>

根据sys.argv[0]就可以处理了啊。

Jiahua Huang

unread,
Feb 22, 2009, 8:45:57 AM2/22/09
to pyth...@googlegroups.com
2009/2/22 flya flya <flya...@gmail.com>:

> 这确实是个问题,似乎mod.__file__比较保险,我一直这样用,但是不知道PY2EXE捆绑之后还行不行了。
>
> linux下快捷方式不能设置"起始位置"确实不太方便,比如我想把python的html格式的document在桌面上建立一个快捷方式,就不行,链接地址都不对,只能先cd到目录下。
>

问题是没有必要啊,
程序你用执行目录换掉工作目录就好(那才是你要的"当前路径")。

而你 html 的"快捷方式",估计其实是软连接,
软连接当然不能有所谓"起始位置", 你用 Windows 的 NTFS 软连接也是一样的。

况且 Linux 下时常会要能从命令行启动,而不是依赖特定的快捷方式( .desktop 菜单项),
这工作路径就是命令行路径了(并非只有终端才是命令行,其他程序调用也是命令行的)

kilnt

unread,
Feb 22, 2009, 11:12:20 PM2/22/09
to pyth...@googlegroups.com


2009/2/22 Long <qujinl...@gmail.com>


Linux下通过cron来部署计划任务的时候出现了问题,程序怎么也不能自动运行,当时因为某些原因没有仔细去查原因到底出在什么地方。


用cron 最好不直接启动 .py 。linux发行版太多,路径和权限,python 安装位置和版本都是问题,
往往生产环境的server 开发人员登录权限都没有,再写个启动脚本更靠谱。


启动脚本 tw.sh

------------------------------------------

export PATH="/usr/local/python:/usr/local/lib/python2.5:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin"

python /home/twserver.py

--------------------------------------------


Zer4tul

unread,
Feb 23, 2009, 1:30:36 AM2/23/09
to pyth...@googlegroups.com
赞分享……很有用的经验啊……

Long 写道:

yingqiang li

unread,
Feb 23, 2009, 5:41:53 PM2/23/09
to pyth...@googlegroups.com
是的,写个启动脚本,是最简单保险的办法!

2009/2/23 kilnt <kiln...@gmail.com>

Elias Soong

unread,
Mar 18, 2009, 5:53:08 AM3/18/09
to pyth...@googlegroups.com

limodou 写道:

> 2. sys.path是Python导入模块时搜索的目录,与当前目录无关。在windows下会自动将运行所在的目录加入sys.path,在linux可能就不同的。不知道你在linux下试过吗?

补充一下,Mac和Linux也会将当前执行目录放入sys.path,也就是说sys.path[0]
和sys.argv[0]的内容是一样的(至少Python 2.5下是这样的)。

总之,举例来讲,os.getcwd()、sys.path[0] (sys.argv[0])和__file__的区别
是这样的:

假设目录结构是:
C:\test
|
[dir] getpath
|
[file] path.py
[dir] sub
|
[file] sub_path.py

然后我们在C:\test下面执行python getpath/path.py,这时sub_path.py里面与各
种用法对应的值其实是:
* os.getcwd() “C:\test”,取的是起始执行目录
* sys.path[0]或sys.argv[0] “C:\test\getpath”,取的是被初始执行的脚本的
所在目录
* os.path.split(os.path.realpath(__file__))[0] “C:\test\getpath\sub”,
取的是__file__所在文件sub_path.py的所在目录

--
----------------------------------------
Personal Site: http://www.elias.cn
----------------------------------------

flya flya

unread,
Mar 18, 2009, 8:10:46 AM3/18/09
to pyth...@googlegroups.com
原来如此,受教了。

2009/3/18 Elias Soong <elias...@gmail.com>:

--
http://www.flyaflya.com

XiongJia Le

unread,
Mar 18, 2009, 10:59:41 AM3/18/09
to pyth...@googlegroups.com
其实我觉得,只要能真确工作,又足够灵活...

以前 看 Apache 的 Unix 版实现好像是这样的:

Appache 的 ServerRoot, 就是 Working Directory.

他好像是这么决定的,默认就用 getcwd 的返回值.
另外也可以用 httpd -d <path>, 指定需要的 Server Root.

之后,一般启动 Apache 的 .sh 脚本里会把绝对路径 写道 -d 参数里. 这样比较灵活. 也可以在各种平台上工作. 不容易错.


2009/2/22 Long <qujinl...@gmail.com>

Jiyue

unread,
Mar 18, 2009, 11:02:34 AM3/18/09
to python-cn`CPyUG`华蟒用户组
真不错,希望能有更多的人分享我们在开发过程的经验!

zanpen2000

unread,
Mar 20, 2009, 11:56:24 PM3/20/09
to python-cn
我想就这个话题问个别的
 
我自己写的module,因为怕乱,不想存放在python的sys.path中,也不用sys.path.append()方法添加,有没有别的方法使得python能找到我的module ?
 
再问下,我试过sys.path.append()不是永久性的,如果能让它变成永久性的,如何做
 
 
2009-03-21

zanpen2000

发件人: Elias Soong
发送时间: 2009-03-18  17:53:23
收件人: python-cn
抄送:
主题: [CPyUG:81604] Re: [分享]关于Python当前路径
limodou 写道:
> 2. sys.path是Python导入模块时搜索的目录,与当前目录无关。在windows下会自动将运行所在的目录加入sys.path,在linux可能就不同的。不知道你在linux下试过吗?

xxmplus

unread,
Mar 21, 2009, 12:03:02 AM3/21/09
to pyth...@googlegroups.com
2009/3/21 zanpen2000 <zanpe...@gmail.com>:

> 我想就这个话题问个别的
>
> 我自己写的module,因为怕乱,不想存放在python的sys.path中,也不用sys.path.append()方法添加,有没有别的方法使得python能找到我的module
> ?
>
> 再问下,我试过sys.path.append()不是永久性的,如果能让它变成永久性的,如何做

放到site-packages里去行不行

--
Any complex technology which doesn’t come with documentation must be the best
available.

limodou

unread,
Mar 21, 2009, 12:38:37 AM3/21/09
to pyth...@googlegroups.com
2009/3/21 zanpen2000 <zanpe...@gmail.com>:

> 我想就这个话题问个别的
>
> 我自己写的module,因为怕乱,不想存放在python的sys.path中,也不用sys.path.append()方法添加,有没有别的方法使得python能找到我的module
> ?
>
> 再问下,我试过sys.path.append()不是永久性的,如果能让它变成永久性的,如何做
>

设置PYTHONPATH或每次执行都执行它。

zanpen2000

unread,
Mar 21, 2009, 5:02:30 AM3/21/09
to python-cn
thanks limodou
 
2009-03-21

zanpen2000

发件人: limodou
发送时间: 2009-03-21  12:39:02
收件人: python-cn
抄送:
主题: [CPyUG:81837] Re: [分享]关于Python当前路径

Samuel Chi

unread,
Mar 22, 2009, 1:25:14 PM3/22/09
to pyth...@googlegroups.com


2009/3/21 zanpen2000 <zanpe...@gmail.com>

我想就这个话题问个别的
 
我自己写的module,因为怕乱,不想存放在python的sys.path中,也不用sys.path.append()方法添加,有没有别的方法使得python能找到我的module ?
 
再问下,我试过sys.path.append()不是永久性的,如果能让它变成永久性的,如何做

可以在python目录下新建.pth文件,里面每行加上相应的绝对路径或者相对路径.
(windows下可以,不知道其他系统下可否正常工作)

tianyi...@gmail.com

unread,
Mar 31, 2009, 8:44:39 AM3/31/09
to python-cn`CPyUG`华蟒用户组
楼主找到把module永久加入sys.path 的方法了吗?分享下。谢谢。

On 3月21日, 下午12时38分, limodou <limo...@gmail.com> wrote:
> 2009/3/21 zanpen2000 <zanpen2...@gmail.com>:

HD

unread,
Mar 31, 2009, 10:11:42 AM3/31/09
to pyth...@googlegroups.com
cron中没有任何环境变量。要注意呀,死过n次人的

2009/2/23 kilnt <kiln...@gmail.com>:

--
HD(燃烧中的火)
我工作我快乐,我勤奋我收获。请与我一起快乐,与我一起收获。

Reply all
Reply to author
Forward
0 new messages