Глобальные переменные в 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 (по крайней мере, я никогда не использовал для чего-то более серьезного, чем то, что я делаю сейчас). Однако я думал, что раньше использовал global аналогично, без этой проблемы.   -  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