2

我有一个 python 脚本,它在其当前工作目录中读取一个名为“data.txt”的文本文件,然后将其中的数据转换为 json 格式,以供另一个单独的程序处理。

我遇到的问题是,当 python 脚本全部捆绑时,我不确定如何读取与 .app 位于同一目录中的 .txt 文件(并编写一个新文件)。我正在使用的当前方法不起作用,因为它是从终端运行而不是作为 .app 执行的事实与它有关?

任何帮助表示赞赏!

4

2 回答 2

2

Mac 上的 .app 在启动时没有任何合理的当前工作目录。

当然它有一些工作目录,你可以很容易地找到它在运行时是什么os.getcwd(),你可以在不同版本的 OS X 上测试各种不同的启动方式来找出所有的模式,但是有什么好处呢?你是这样吗?

好消息是,您显然并不真正想要当前的工作目录。您需要 .app 包或 .exe 的目录。

换句话说,如果有人这样做:

C:\Users\foo> C:\Stuff\MyProgram.exe

您想要C:\Stuff(可执行文件的目录),而不是C:\Users\foo(工作目录)。

在 Windows 上,这很容易。.exe 只是一个文件,它的路径将是__path__您在 Python 中获得的路径,因此:

import os
pathToApp = os.path.dirname(__path__)

在 Mac 上,这更难。.app 是一个包——一个包含其他文件和目录的目录。在某个地方有一个可执行解释器和你的脚本的副本,并且__path__会给你后者,而不是 .app 的路径。

正确的方法是使用 Cocoa(或 CoreFoundation):

import Cocoa
pathToApp = Cocoa.NSBundle.mainBundle().bundlePath()

If you don't want to do that, you pretty much have to rely on some information that the documentation says you can't rely on and could change some day. But the following code should be safe:

import os
pathToApp = __file__
while not pathToApp.endswith('.app'):
  path = os.path.dirname(path)

In order for this to stop working, either the script would have to be outside the .app bundle, or inside another .app inside the one you're looking for, or bundles would have to stop being named .app, or they'd have to stop being structured as normal directories; none of this seems likely to change in OS X 10.*, or even OS Y 11.

As a side issue: what you're trying to do is most likely a bad idea in the first place. A Mac application shouldn't be working with files alongside it. Conversely, if users are going to expect to work on files alongside it, you probably want a simple Unix executable (or just a plain Python script with chmod +x), not an application.

于 2012-09-20T21:40:44.110 回答
0

使用__file__变量。这将为您提供模块的文件名。使用中的函数os.path可以确定模块父目录的完整路径。该os.path模块在标准 python 文档中,您应该能够找到它。

然后你可以将模块路径与你的文件名结合起来打开它,使用os.path.join.

于 2012-09-20T20:28:39.353 回答