Глобални променливи в Python с имена на файлове

Пиша програма на Python 3 с Tkinter, която работи под Windows 8.1.

Трябва да избера две папки, които ще се използват заедно в друга функция. В момента имам два бутона за избор на файл, които отварят диалоговия прозорец за избор на папка:

def select_file_1(self):
    global first_file
    first_file = filedialog.askdirectory()

def select_file_2(self):
    global second_file
    second_file = filedialog.askdirectory()

Те работят правилно: всеки път, когато се щракне върху бутоните, той се появява и пита за директория.

След това има само още един път, когато се използват променливите first_file и second_file, които също отбелязвам като глобални променливи, преди да ги използвам. Това е, когато е избран друг бутон:

def create_composite(self):
    global first_file
    global second_file

    f1 = open(first_file, "r")
    f2 = open(second_file, "r")

Това обаче води до следната грешка: NameError: name 'first_file' is not defined при опит за четене на реда по-горе, започващ с f1 = open.

Ако това помага за яснота, ето съответната част от моя интерфейс на екранната снимка по-долу. select_file_1 се извиква чрез щракване върху първия избран файл, а select_file_2 се извиква чрез щракване върху втория избран файл. След това create_composite се извиква чрез щракване върху създаване на клас.

екранна снимка за яснота


person Jake    schedule 09.01.2015    source източник
comment
Не знам какво причинява проблема ви, но защо вместо това не ги направите атрибути на self? Като self.first_file и self.second_file. (или евентуално дори само self.files)   -  person Kevin    schedule 09.01.2015
comment
За 10+ години програмиране в python все още не съм използвал ключовата дума global. Ако го използвате, има вероятност да преструктурирате кода си.   -  person Gerrat    schedule 09.01.2015
comment
@Gerrat, от време на време преработвам класовете сингълтън в модули, след което променливите членове се превръщат в глобални модули - и методите се превръщат във функции, които използват global :) Не съм сигурен дали това е добър модел обаче... или дали сингълтоните са.   -  person André Laszlo    schedule 09.01.2015
comment
Кевин, ще опитам това. Герат, възможно е; Нов съм в Python (поне никога не съм го използвал за нещо толкова сериозно като това, което правя сега). Мислех обаче, че съм използвал глобално по подобен начин преди, без този проблем.   -  person Jake    schedule 09.01.2015
comment
Дали функцията create_composite() е същият py файл като двете функции select_file_x()? global се отнася само за модула, в който се намира всичко -- Python няма наистина глобални променливи.   -  person martineau    schedule 09.01.2015
comment
martineau, да, всички в същия .py файл.   -  person Jake    schedule 09.01.2015
comment
Кевин, опитах да преструктурирам към използване на себе си. Не съм сигурен къде е проблемът. Изглежда проблемът е, че filedialog.askdirectory() не съхранява директорията като низ, където трябва. Промених го на себе си и първоначално дефинирах низа като равен на '' (празно). След това, въпреки че се появява диалогов прозорец и е избрана папка, все още получавам тази грешка, когато се опитвам да отворя файла: FileNotFoundError: [Errno 2] No such file or directory: ''   -  person Jake    schedule 09.01.2015
comment
можете ли да покажете пълното, действително проследяване на стека?   -  person Bryan Oakley    schedule 09.01.2015
comment
Брайън, кой е най-бързият начин да направиш това? Предполагам, че имате предвид нещо повече от изхода на терминала?   -  person Jake    schedule 10.01.2015
comment
Вероятно сте получили повече от NameError: името 'first_file' не е дефинирано -- получавате половин дузина редове или повече, показващи номера на редове и стека на повикванията.   -  person Bryan Oakley    schedule 10.01.2015
comment
@Jake, публикувай пълно проследяване на стека (изход по подразбиране в терминала). Освен това това предполага, че нямате променлива first_file във външния обхват   -  person Reut Sharabani    schedule 10.01.2015
comment
Възможно ли е функцията create_composite() да бъде извикана преди select_file_1() да бъде извикана? В противен случай first_file няма да съществува.   -  person martineau    schedule 10.01.2015
comment
В create_composite глобалните декларации не са необходими за достъп само за четене до имената.   -  person Terry Jan Reedy    schedule 10.01.2015


Отговори (1)


Фрагментите, които сте публикували, работят правилно, стига select_file_1() и select_file_2() да се извикват преди create_composite.

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

О, и filedialog.askdirectory връща името на директория, а не на файл - опитвайки се да отворите това не е добра идея.

person Ethan Furman    schedule 27.05.2015