0

私の Mac OS アプリには Python.framework (v 2.7) が含まれているため、「リンクされたフレームワーク」に必須として追加しました。また、アプリでは、次のような NSTask を使用して Python スクリプトを起動しています。

//...
pythonEnv = [[[NSBundle mainBundle] privateFrameworksPath] stringByAppendingPathComponent:@"Python.framework/Versions/2.7/bin/python"];
task = [[NSTask alloc] init];
outPipe = [NSPipe pipe];
readHandle = [outPipe fileHandleForReading];
data = [[NSMutableData alloc] init];

args = [NSArray arrayWithObjects: scriptPath, kbt, server, port, username, password, nil];

[task setArguments:args];
[task setLaunchPath: pythonEnv];

readHandle = [outPipe fileHandleForReading];
[task setStandardInput:[NSPipe pipe]];
[task setStandardOutput:outPipe];
[task launch];
[task waitUntilExit];
//...

アプリをビルドし、Python スクリプトで使用するバージョンを確認するとsys.path、次のように返されます。

["/Users/...スクリプトへのパス.../Contents/Resources"、"/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip"、"/Library/Frameworks/Python.framework /Versions/2.7/lib/python2.7", "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin", "/Library/Frameworks/Python.framework/Versions/2.7 /lib/python2.7/plat-mac", "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages", "/Library/Frameworks/Python.framework /Versions/2.7/lib/python2.7/lib-tk", "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old", "/Library/Frameworks/Python.framework /Versions/2.7/lib/python2.7/lib-dynload", "/Users/tatiana/Library/Python/2.7/lib/python/site-packages", "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages", "/Library/Python/2.7/site-packages"]

...含まれているフレームワークを使用していません。他にどこで正しいパスを設定する必要がありますか? ビルド設定で忘れているものはありますか?

更新 1 ------------------------

タスク環境を設定せず、Python で をテストするとsys.executable、次のようになります。

/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python

...私のフレームワークを使用していないようです。タスク環境を次のように設定した場合:

// pythonEnv = [[[NSBundle mainBundle] privateFrameworksPath] stringByAppendingPathComponent:@"Python.framework/Versions/2.7/bin/python"];
NSDictionary *environment = [NSDictionary dictionaryWithObjectsAndKeys: pythonEnv, @"PYTHONPATH", nil];
[task setEnvironment:environment];

それをテストしても、同じ結果が得られます。しかし、Python で でテストするとos.environ["PYTHONPATH"]、次のようになります。

/Users/tatiana/Desktop/MyApp.app/Contents/Frameworks/Python.framework/Versions/2.7/bin/python

それはもう少し有望に見えますが、なぜ sys.executable が私にそれを与えないのか混乱しています。

更新 2

私のbin/pythonは実行可能ファイルではなかったので、python2.7に変更しました。sys.executableデフォルトが Library/... であることをまだ示しています

pythonEnv = [[[NSBundle mainBundle] privateFrameworksPath] stringByAppendingPathComponent:@"Python.framework/Versions/2.7/bin/python2.7"];
NSString *searchPath = [[[NSBundle mainBundle] privateFrameworksPath] stringByAppendingPathComponent:@"Python.framework/Versions/2.7/lib/python2.7"];
NSDictionary *environment = [NSDictionary dictionaryWithObjectsAndKeys: searchPath, @"PYTHONPATH", nil];
[task setEnvironment:environment];
4

2 に答える 2

0

これは既知のバグである可能性があります。この古いメーリング リストの投稿、bugs.python.org のこの最近のバグを参照してください

Python 2.7.3 の Modules/getpath.c に次のコメントがあります。

 /* On Mac OS X, if a script uses an interpreter of the form
  * "#!/opt/python2.3/bin/python", the kernel only passes "python"
  * as argv[0], which falls through to the $PATH search below.
  * If /opt/python2.3/bin isn't in your path, or is near the end,
  * this algorithm may incorrectly find /usr/bin/python. To work
  * around this, we can use _NSGetExecutablePath to get a better
  * hint of what the intended interpreter was, although this
  * will fail if a relative path was used. but in that case,
  * absolutize() should help us out below
  */

これはあなたには直接当てはまらないかもしれませんargv[0]が、実行された python プロセスでは"python". コメントに記載されているハックが失敗した場合、またはバージョンに存在しない場合、Python は Python インタープリターへの絶対パスを調べ$PATHて見つけようとします。_NSGetExecutablePathにないフレームワーク$PATHは無視されるため、システム Python を見つけて使用します。

これはいくつかの方法で確認できます。デバッガーでブレークポイントを設定し、NSTask最終的に に渡される引数を調べることができますexec()。または、ps axPython プロセスを調べて見つけて (スクリプトに PID を出力してから永久に実行すると役立つ場合があります)、最初の引数がフレームワークへのフル パスであるかどうかを確認できます。または、スクリプトをチェックアウトすることもできsys.argv[0]ます (おそらく、変更されている可能性があります)。

これが実際に問題である場合、修正は適切なargv[0]セットを取得することです。でそれを行う方法がわかりません。そのNSTaskため、次の最善の策は、おそらく環境変数bin/にPython フレームワークへのパスを含めることです。PATH少なくとも、Python は の正しい値を推測できますsys.executable

または、スクリプト内で が本当に気にならない場合sys.executableは、Python が実際に実行されているものであると判断した後、 dispite をそのままにしておくことができますsys.executable

于 2013-01-03T13:36:38.720 に答える
0

関連する 2 つのことを混同しているようです。

  1. アプリ バンドル内にある Python 実行可能ファイルの起動
  2. App Bundle 内の Python lib フォルダーを含むように Python 検索パスを設定する

実行する Python 実行可能ファイルのパスを設定するにはNSTask、そのlaunchPath. Python では、 を使用して値にアクセスできますsys.executable

Python の検索パスを操作するには、フレームワークのフォルダー-[NSTask setEnvironment:]PYTHONPATH設定して呼び出します。Python では、 でそのパスにアクセスできます。lib/python2.7sys.path

于 2012-12-27T00:52:00.947 に答える