Есть несколько проблем с вашим подходом, некоторые ошибки кодирования, некоторые концептуальные.
Проблема с понятием:
Как я заметил, основная проблема заключается в том, что вы, кажется, думаете, что помещение некоторого текста в файл, представляющий собой последовательность разделенных запятыми квадратных скобок, заключенных в двойные кавычки, приведет к созданию списка в вашем Python. программа при чтении с использованием дескриптора файла с readlines()
.
Более того, когда вы жаловались на напечатанную заключенную в одинарные кавычки строку, вы, похоже, ожидали, что прочитанное из файла будет напечатано в виде отдельных квадратных скобок (возможно, каждый в одной строке?) вместо одной строки.
Во-первых, в тексте, прочитанном из файла, есть , а не списки Python.
Исходный код Python интерпретируется только как исходный код с операторами и данными, такими как числа, списки, кортежи и т. Д., Поскольку они читаются интерпретатором Python.
Когда вы open()
файл и затем вызываете readlines()
для дескриптора файла, это не интерпретатор Python, который читает файл. На самом деле, на низком уровне, это ядро, которое читает файл кусками соответствующего размера и помещает его в память, а именно в часть памяти, к которой относится ваша переменная allthequestions
.
Подумайте об этом: если бы первая теория была верной, то использование readlines()
для файла фактически выполняло бы все, что было похоже на команду Python.
Тогда как бы он вообще знал, что вернуть? Возможно, результат последнего выражения? Список всех результатов выражения в файле? Кортеж из них? Независимо от того, как мы смотрим на это, было бы трудно определить, каково даже ваше ожидаемое поведение для readlines()
.
С такими вещами лучше всего экспериментировать на отдельных небольших примерах, прежде чем использовать их в полной программе.
Кроме того, как следует из названия, readlines()
читает текст как строки , а не как разделенные запятыми списки Python или любые другие токены.
Результатом, хотя и не списком, является итеративная коллекция всех строк в файле. Это означает, что в вашем случае - в соответствии с тем, что вы написали - это одна строка, содержащая:
["What would you wear to work?","Hoodie", "Suit", "Shorts","2"],["How would you greet a customer?","Hey", "Hi", "Hello", "0"],["How many years of experience do you have?","Loads", "None", "Some","1"],["Why do you want to work here?","It's fun", "No money", "Friend told me to","2"]
, включая перевод строки в конце.
Проверяя эту структуру данных, кажется, что вы хотите проанализировать одну последовательность последовательностей из файла, где каждая вложенная последовательность содержит текстовые элементы. Первый (или, другими словами, 0-й) элемент каждой вложенной последовательности является вопросом, тогда как любой другой текстовый элемент является возможным ответом на этот вопрос.
Что означает число в последнем элементе, я не смог расшифровать.
Решения:
Вы можете использовать метод синтаксического анализа текста, называемый «регулярные выражения», но он может быть слишком сложным для того, чего вы пытаетесь достичь.
Вместо этого я бы предложил выбрать другую структуру данных .
Если вы хотите обрабатывать ваши данные только на Python, я бы предложил метод сериализации , например, модуль pickle
.
Этот модуль позволяет записывать объект python в файл в таком формате, чтобы его можно было снова прочитать в переменную (конечно, НЕ с readlines()
, который предназначен для чтения строк, а не объектов).
Чтобы продемонстрировать, как это работает в конце записи и чтения, вот несколько фрагментов кода:
Пример для пишущего компонента:
# write_questions.py
import pickle
all_the_questions = (["What would you wear to work?","Hoodie", "Suit", "Shorts","2"],["How would you greet a customer?","Hey", "Hi", "Hello", "0"],["How many years of experience do you have?","Loads", "None", "Some","1"],["Why do you want to work here?","It's fun", "No money", "Friend told me to","2"])
questions_file = open("questions.dmp", "w")
pickle.dump(all_the_questions, questions_file)
questions_file.close()
Пример для компонента чтения:
# read_questions.py
import pickle
questions_file = open("questions.dmp")
all_the_questions = pickle.load(questions_file)
print(all_the_questions[0])
print(all_the_questions[1])
Структура данных all_the_questions
представляла собой кортеж из списков строк, который был выгружен в файл "questions.dmp" с использованием pickle.dump()
.
Обратите внимание, что созданный файл "questions.dmp" содержит специальную запись объекта, которая используется pickle
для считывания его содержимого обратно в качестве переменной и не читается человеком!
Как только вы запустите часть чтения, вы увидите, что индексирование по переменной all_the_questions
работало правильно после того, как переменная была создана из содержимого файла с использованием pickle.load()
, и вы получили что-то вроде этого, записанное в ваш терминал:
['What would you wear to work?', 'Hoodie', 'Suit', 'Shorts', '2']
['How would you greet a customer?', 'Hey', 'Hi', 'Hello', '0']
Другим решением было бы использование стандартного формата текстовых данных, например CSV (значения, разделенные запятыми), для которого в стандартной библиотеке Python есть анализаторы.
По сути, вы можете хранить каждый список вопросов в виде отдельной строки в файле «questions.csv», не разделяя его символами []
, и каждая строка может занимать позицию между запятыми в строке вопроса, например:
What would you wear to work?,Hoodie, Suit, Shorts,2
How would you greet a customer?,Hey, Hi, Hello, 0
How many years of experience do you have?,Loads, None, Some,1
Why do you want to work here?,It's fun, No money, Friend told me to,2
Ответ уже слишком длинный, поэтому я предоставляю читателю интерес к использованию анализа CSV, чтобы посмотреть, как он работает. Есть несколько доступных ресурсов, так же как для маринада.
Преимущества состоят в том, что данные, хранящиеся в файле, будут удобочитаемыми, и их обработка не будет ограничена программами Python, поскольку CSV - довольно часто используемый старый формат.
Проблемы с кодированием:
Предыдущий раздел уже касался части кода, касающейся readlines()
, но есть еще некоторые проблемы.
Во-первых:
forbuttons=[print(allthequestions)]
Эта строка печатает текстовое представление объекта коллекции, хранящегося в allthequestions
, преобразует возвращаемое значение print
в список и связывает полученное значение с forbuttons
.
Поскольку print()
всегда возвращает значение None
, значение forbuttons
будет одноэлементным списком, содержащим только None
.
Напечатано, это будет выглядеть примерно так:
[None]
Далее
textquestions.close
строка на самом деле не вызывает функцию close()
для дескриптора файла, она только оценивает объект функции , ничего не делая.
Затем исходный фрагмент пытается вызвать объект в forbuttons
с аргументом 0
, как если бы это была функция. Увы, это не так, это список [None]
, как объяснено выше:
q1 = forbuttons(0)
Впоследствии вы вдруг решаете трактовать forbuttons
как индексируемый список вместо функции, многомерного!
buttonq1 = tk.Button(self, text=forbuttons[q1][0])
Если честно, я действительно понятия не имею, что это даст вам, поэтому я не могу предложить альтернативу.
Возможно, вы хотели сделать что-то вроде:
buttonq1 = tk.Button(self, text=allthequestions[0][0])
, где текст кнопки будет установлен на самый первый вопрос, если бы вы использовали, например, рассол вместо readlines()
.
Другая проблема, которую я нахожу в вашем представлении данных, заключается в том, что вы в основном используете магические числа, такие как 0
, чтобы запомнить, где находится фактическая часть вопроса в списке вопросов.
Может быть, использовать словарь, где ключ является фактической строкой вопроса, и значение возможных ответов будет лучше. В этом случае структура одного вопроса будет выглядеть так:
{ "What would you wear to work?" : ["Hoodie", "Suit", "Shorts","2"] }
Соглашение об именах также причудливо по нескольким причинам:
Во-первых, неоднозначно, что к чему. Является ли «вопрос» целой структурой данных, которая включает в себя строку вопроса, как это было бы задано человеком, а также возможные ответы? Или это просто строка вопроса?
Второе: переменные в общем случае не соответствуют каким-либо нормальным правилам именования. Обычные соглашения об именах включают «camelCase», «PascalCase» (или верхний регистр верблюда), «snake_case» и т. Д.
Руководство по стилю Python, PEP-8, рекомендует использовать «snake_case» для переменных и функций, «UPPER_SNAKE_CASE» для переменных, которые должны быть постоянными, и «PascalCase» для имен типов.
приписка
В общем, прежде чем применять их, особенно вместе, нужно всегда изучать и знать, что / что делает каждая концепция, функция и т. Д.
Это требует большой практики и экспериментов, а также изучения документации.
Если честно, первоначальный вопрос совсем не выглядит так, будто в него было вложено много исследований или работ.
Несмотря на это, мне это не понравилось, так как оригинальный постер был новым автором и, как кажется, довольно новым для программирования.