pyinstaller изглежда не намира файл с данни

Редактиране 3: Замених __file__ с sys.argv[0], когато трябва да знам местоположението на моя скрипт/изпълним файл. Това не е точно същото, но в моя случай изглежда, че работи добре (поне на изпълнима версия...). Сега всичко работи добре, в режим на един файл, с използване на функцията за приет отговор за достъп до файлове с ресурси!


Редактиране 2: както е показано в коментарите на приетия отговор, проблемът идва от разрешаването на пътя в моя скрипт; Опитвам се да използвам __file__, за да получа местоположението на скрипта, така че да имам достъп до неговите файлове с ресурси. Това не работи, след като е пакетирано, тъй като __file__ ще върне име на файл от Python.dll към скрипта, така че винаги няма път и само име на файл. Така че трябва да намеря друг трик, за да направя достъп до файлове с ресурси; заобиколно решение за момента е да преместите текущата директория в изпълнимия път.

Между другото, това означава, че ConfigParser трябва да съобщи за проблем при достъп до файла, а не че липсва раздел.

Ще актуализирам този въпрос с начина, по който разреших този въпрос за разрешаване на пътя.


Имам проблеми с pyinstaller и тъй като го използвам за първи път, сигурно съм направил нещо нередно.

И така, ето го проблемът: pyisntaller работи гладко на скрипт, който написах, и генерира някои неща в папка dist. Добре, сега искам да го изпълня, за да видя дали всичко е минало добре, и ето какво получавам:

C:\Program Files\PyInstaller\pyinstaller-1.5.1>p_tool\dist\p_tool\p_tool.exe -?
Traceback (most recent call last):
  File "<string>", line 104, in <module>
  File "p_tool\build\pyi.win32\p_tool\outPYZ1.pyz/logging.config", line 76, in f
ileConfig
  File "p_tool\build\pyi.win32\p_tool\outPYZ1.pyz/logging.config", line 112, in
_create_formatters
  File "p_tool\build\pyi.win32\p_tool\outPYZ1.pyz/ConfigParser", line 532, in ge
t
ConfigParser.NoSectionError: No section: 'formatters'

Първата ми идея беше, че файлът logging.conf липсва, така че го добавих (и някои други файлове с ресурси) във файла p_tool.spec, но това не е по-добро.

Python версия: 2.6.6, под WinXP. Използвам pyinstaller, тъй като ще ми трябва за пакетиране на файлове за работна станция Solaris.

И така, някой имал ли е този проблем? Единствената свързана тема е следният въпрос: Проблем с PyInstaller, много близо до моя проблем, но безнадеждно няма отговор .


Редактиране 3: подробностите за регистрирането са премахнати, тъй като всъщност не са свързани с проблема.


person Joël    schedule 20.10.2011    source източник
comment
това изглежда по-добро решение: stackoverflow.com/questions/404744/   -  person Gonzo    schedule 08.09.2012
comment
Правилно, благодаря за линка!   -  person Joël    schedule 28.11.2013


Отговори (3)


Първо, може да е разумно да направите печат config_file / os.path.exists(config_file), преди да го прочетете, така че да сте сигурни къде е файлът и дали python може да го намери.

Що се отнася до действителния достъп до него, os.path.split(__file__) изглежда почти правилно, но не съм сигурен, че работи правилно под pyinstaller - правилният начин за опаковане на файлове е да ги добавите към .spec файла, след което pyinstaller ще ги зареди по време на компилиране и ще ги разопакова към $_MEIPASS2/ по време на изпълнение. За да получа директорията _MEIPASS2 в опакован режим и да използвам локалната директория в разопакован (разработващ) режим, използвам това:

def resource_path(relative):
    return os.path.join(
        os.environ.get(
            "_MEIPASS2",
            os.path.abspath(".")
        ),
        relative
    )


# in development
>>> resource_path("logging.conf")
"/home/shish/src/my_app/logging.conf"

# in deployment
>>> resource_path("logging.conf")
"/tmp/_MEI34121/logging.conf"
person Shish    schedule 25.10.2011
comment
Този отговор е пълен с добри съвети. И така, първо, отпечатването на пътя, който търся, показва, че __file__ се разрешава като скрипт, спрямо Python.dll, което означава, че в моя случай os.path.split(...)[0] винаги е празен. Казано по друг начин, все едно моят скрипт ще бъде локален за всяко място, където се извиква... Така че сега трябва да намеря друг начин за достъп до моите файлове с ресурси. :-/ - person Joël; 25.10.2011
comment
За да завършите предишния коментар: ако се преместя в изпълнима папка, преди да я изпълня, разделителната способност на пътя е наред и сега инструментът стартира правилно! И така, сега трябва да разбера как да дефинирам разделителната способност на пътя в моя код на Python, за да го накарам да работи, и това е друга тема. Относно функцията resource_path, със сигурност ще бъде полезна, когато опитам пакетиране с един файл. Така че вашият отговор си заслужава наградата! Благодаря за вашата помощ :-) - person Joël; 25.10.2011
comment
MEIPASS или MEIPASS2? От къде знаеш? - person dranxo; 06.11.2013

Съобщението за грешка ConfigParser.NoSectionError: No section: 'formatters' предполага, че това не е липсващ файл, а файл с липсващ раздел, който трябва да търсите.

person Tavis Rudd    schedule 24.10.2011
comment
Актуализирах въпроса, но се съмнявам, че наистина е проблем от този файл, тъй като версията на Python работи без проблем. Така че мисля, че това е по-скоро проблем с достъпа до файла. - person Joël; 24.10.2011

Имах подобен проблем, но досега не можах да намеря елегантно решение. „Хакът“, който използвам, който ме накара да се справя, да кажем, че проектът ми се намира в '~/project/project_root', първо във файла .spec:

excluded_sources = TOC([x for x in a.pure if not x[0].startswith('project_root')])

Тук a е обектът Analysis, по принцип премахвам всички мои файлове с проекти от PYZ, така че там не се предава импорт и относителните пътища на регистратора няма да бъдат изчислени оттам. След това създайте Tree обект от проекта.

my_project_tree = Tree('~/project')

След това добавете това дърво към списъка с TOC, който се предава на COLLECT, така че:

COLLECT( exe,
           a.binaries,
           a.zipfiles,
           a.datas,
           my_project_tree,
           ....)

Трябва да добавите папката на вашия проект към папката dist. Проблемът е, че в крайна сметка ще разпространявате и pyc на вашия проект, но досега не можете да намерите по-добър начин. Много се интересувам от валидното решение.

person Bogdan    schedule 24.10.2011
comment
Ммм добре, изглежда трудно, но не е извън моя обхват. Въпрос обаче: файловете pyc ще бъдат ли изпълнени с вградения изпълним файл на Python? Искам да кажа, това ще работи ли на всеки компютър със или без инсталиран Python? - person Joël; 24.10.2011
comment
Да, трябва да бъдат, стига да е същата операционна система. Тествах го само на debian squeeze, но не мога да гарантирам. - person Bogdan; 24.10.2011
comment
Добавих още подробности относно конфигурацията на регистриране. Може ли да погледнете, моля? Може би начинът, по който конфигурирах ресурсните си файлове, води до проблеми с PyInstaller. - person Joël; 25.10.2011
comment
Втори коментар относно вашия код: използвате ли excluded_sources както следва: pyz = PYZ(a.pure - excluded_sources)? Ако да, тогава може би not е твърде много в for x in a.pure if *not* x[0].startswith(.... Може да не съм го разбрал, тъй като все още не работи; но наличието на pyc файлове все пак е по-добре от нищо, ако е пакетирано за всяка версия на Python. - person Joël; 25.10.2011
comment
Ето малко новини. Проблемът идваше от факта, че __file__ не връщаше очакваната стойност. И така, в крайна сметка използвам sys.argv[0], за да определя местоположението на извикания изпълним файл. Надявам се да няма страничен ефект от това, тъй като това е всичко, което мога да си представя, за да заобиколя този проблем. Благодаря все пак за помощта! - person Joël; 25.10.2011
comment
@Bogdan: Вашият хак ми свърши работа на Windows. Имам въпрос обаче. След като стартирам pyinstaller, след като направих някои промени в моите скриптове на python, няма ли да трябва да стартирам pyinstaller отново срещу .py файла, за да генерирам нова спецификация? Ако е така, тогава ще трябва да правя тези промени всеки път, когато правя промени в скрипта, преди да създам exe. Има ли начин да се заобиколи това? - person Crypto; 07.02.2014