Модулът не може да бъде намерен, когато се използва pythonw (вместо python) за изпълнение на приложение

Опитах този минимален пример:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run(debug = True)

Когато пробвам python hello.py, всичко върви добре. Въпреки това, когато се опитам да го стартирам от Textmate (Shift + Cmd + R), се извежда грешка:

Traceback (most recent call last):
  File "/Users/user/EventFeed/hello.py", line 1, in <module>
    from flask import Flask
ImportError: No module named flask

Textmate извиква pythonw вместо python. Когато опитам pythonw сам се извежда същата грешка.

man pythonw гласи, че От Python 2.5, python и pythonw са взаимозаменяеми, въпреки че изглежда не са в този случай.

Имате ли идея какво се случва?

(Въпрос Код, който работи с python, а не с pythonw не отговаря на въпроса въпреки подобното му заглавие.)


person Thibaud    schedule 25.09.2014    source източник
comment
Сигурни ли сте, че вашите python и pythonw са от една и съща инсталация на Python? От командния ред стартирайте всеки един, след това import sys; print sys.executable, sys.path и вижте какво казват.   -  person abarnert    schedule 26.09.2014
comment
Изчакайте секунда, това е Mac, а не Windows... само which python и which pythonw в подканата за bash ще го направят. И съм 90% сигурен, че вече знам какво ще видите.   -  person abarnert    schedule 26.09.2014


Отговори (1)


Проблемът е, че вашите pythonw и вашите python не сочат към едни и същи инсталации на Python.

Защо?

Най-вероятно защото сте инсталирали втори Python 2.7, който не включва остарелия pythonw, но предварително инсталираният Python 2.7 на Apple определено го включва.

Най-бързият начин да проверите това е командата which. Например на една от моите машини:

$ which python
/usr/local/bin/python
$ which pythonw
/usr/bin/pythonw

Първият е символна връзка към Homebrew инсталация на Python 2.7, докато вторият е Python 2.7 на Apple. Вашите точни данни може да се различават; първият може да е символна връзка към /Library/Frameworks/Python.framework/Versions/2.7/bin/python или изпълним файл за обвивка, който всъщност живее в /usr/local/bin, или може да е в /opt/local и т.н. Въпросът е, че те не са в едни и същи директории.

Във всеки случай вашите две отделни инсталации на Python не споделят едни и същи сайт-пакети (и не трябва), така че фактът, че сте инсталирали Flask за втората, не помага на тази на Apple. Можете да проверите това, като ги стартирате и разпечатате sys.path:

$ python
>>> import sys
>>> sys.path
['', '/usr/local/lib/python2.7/site-packages', …]
>>> ^D
$ pythonw
>>> import sys
>>> sys.path
['', '/Library/Python/2.7/site-packages', …]
>>> ^D

Както и да е, най-простото решение е да конфигурирате вашия редактор да изпълнява python вместо pythonw или, по-добре, да му дадете абсолютен път към интерпретатор на Python като /usr/local/bin/python2.7, за да сте абсолютно сигурни, че знаете какво изпълнявате.

(Не познавам много добре TextMate, но от този източник изглежда, че има настройка с име TM_PYTHON, която трябва да контролира това...)

person abarnert    schedule 25.09.2014
comment
Прав си. python се свързваше с virtualenv python, който самият се свързваше с Homebrew python, докато pythonw се свързваше директно с Homebrew pythonw. Причината е, че pythonw не е включен в директория, когато virtualenv venv и целта на virtualenv е точно да изолира пакетите, дори ако изпълнимите файлове се свързват към една и съща крайна точка. - person Thibaud; 26.09.2014
comment
@Thibaud: А, не се сетих за virtualenv, защото никога не съм настройвал IDE да работи с virtualenv, но виждам как това би причинило проблема. Така че подробностите в моя отговор всъщност не са правилни; мислиш ли, че трябва да го редактирам? - person abarnert; 26.09.2014
comment
Не споменах virtualenv във въпроса си, така че отговорът ви е напълно добър, защото е достатъчно общ, за да се приложи и в двата случая, но същевременно е достатъчно точен, за да ме накара да уловя проблема. - person Thibaud; 27.09.2014