Я хочу создать переменную с именем this_is_the_first_run, которая будет храниться в файле main.py и должна указывать, выполняется ли это первый раз, когда проект запускается. По сути, код, который я пытаюсь написать, выглядит так:
If this_is_the_first_run == 1:
os.system('python first_run.py')
Но я не знаю, где назначить и сохранить эту переменную, поскольку не могу поместить ее в свой first_run.py. Я также не могу присвоить значение этой переменной где-то в основном файле. Каков наилучший подход к этому?
Переменные, генерируемые во время выполнения кода, сами по себе не существуют после выполнения вашего кода. Если вы хотите, чтобы значения переменных сохранялись после выполнения кода, вам необходимо записать значения, которые вы хотите сохранить, в файл на диске, а затем получить доступ/прочитать/записать эти файлы в рамках выполнения вашего кода.
Пример того, как вы можете достичь того, что вы описываете, приведен ниже:
# This is the main function. Each time it's run, the variable "run_count" is
# retrieved by reading run_count.txt, and its value is incremented by 1, and
# written back to run_count.txt.
def main():
# check if "run_count.txt" exists. If it does, read its current count and
# assign it to the variable run_count.
try:
with open('run_count.txt', 'r') as f:
run_count = int(f.read())
# If run_count.txt does not yet exist, create it and write the value 0 to it.
except FileNotFoundError:
with open('run_count.txt', 'w') as f:
run_count = 0
f.write(str(run_count))
# Insert actual main() code here:
print ("Now the script does whatever you want.")
# Now that your main() function has been run, increment the value of run_count
# by 1 and write the new value to run_count.txt.
run_count += 1
with open('run_count.txt', 'w') as f:
f.write(str(run_count))
# print the current run_count to screen
print(f'This script has been run {run_count} {"times." if run_count > 1 else "time."}')
main()
# Now the script does whatever you want.
# This script has been run 1 time.
main()
# Now the script does whatever you want.
# This script has been run 2 times.
main()
# Now the script does whatever you want.
# This script has been run 3 times.
main()
# Now the script does whatever you want.
# This script has been run 4 times.
main()
# Now the script does whatever you want.
# This script has been run 5 times.
В этом случае в текстовый файл записывается одно значение. Если вы хотите, чтобы несколько значений или более сложные структуры данных сохранялись, существует множество доступных вариантов — от использования больших/длинных txt-файлов, csvs, jsons или баз данных.
Я настоятельно не рекомендую использовать обычные текстовые файлы для хранения данных. Использование int()
— крайне плохая идея, потому что, если файл содержит новую строку, он сломается.
Конечно, текстовый файл — не лучший способ сохранения данных — я использовал его здесь, чтобы познакомить спрашивающего с основным понятием чтения/записи файлов как способа сохранения значений. Из этого вопроса я сделал вывод, что «json» может быть новой концепцией для пользователя, и постарался сохранить ее базовой.
Такого поведения можно добиться с помощью файла конфигурации. Чтобы отличить первый запуск от последующих, вы можете просто использовать наличие файла конфигурации в качестве индикатора.
import json
import pathlib
# the config file is in the same directory as this python file
config_path = pathlib.Path(__file__).parent / 'config.json'
# equivalent but, the config file is stored in the same directory
# as the __main__ python file, e.g. if you run `python index.py` then index.py is __main__.py
config_path = pathlib.Path('config.json')
# if file doesn't exist,
# assuming it wasn't deleted by user previously
# then this is definitely the first run
first_run = not config_path.exists()
if first_run:
# it is important to create the file on the first run
with config_path.open('wt') as f:
f.write("{}") # empty json
# equivalent line using a dictionary
json.dump({}, f)
# do your other stuff
На вопрос нужен полный, исчерпывающий, но простой ответ, которого я не думаю pathlib
. Большинство программистов Python знают, как использовать json
, но не pathlib
. Кроме того, ваш код содержит много дубликатов. Например, f.write("{}")
и json.dump({}, f)
делают одно и то же, только по-разному. Рассмотрите возможность использования только json.dump()
.
Переменные Python определяются только при запуске данной программы и исчезают сразу же, как только программа завершает выполнение. Если вы хотите, чтобы переменная жила за пределами текущей исполняемой программы, попробуйте использовать json и файлы, например:
import json
import os
if os.path.exists(path:=os.path.join(os.getcwd(), 'run_times.json')):
with open(path, 'r') as fp:
times = json.load(fp)+1
print(f'executed this file {times} times')
with open(path, 'w') as fp:
json.dump(times, fp)
else:
with open(path, 'w') as fp:
json.dump(1, fp)
print(f'executed this file 1 time')
# do what you want here
Этот подход надежен и адаптируется ко всем видам операционных систем, условий и объектов. Использование json лучше, чем использование обычных текстовых файлов, поскольку вы можете положиться на библиотеку для извлечения значений, а не на извлечение значений самостоятельно. Кроме того, приведенный выше код использует библиотеку os
для проверки существования файла. Хотя попытка открыть файл и перехватить FileNotFoundError
работает, она вызывает ненужные исключения. Таким образом, я предлагаю использовать библиотеку json
для обработки данных и библиотеку os
для проверки существования файла, а не вызывать исключение.
Вызов и перехват исключений — это путь Python, не нужно этого бояться.
Нет необходимости в JSON, если вам просто нужен маркер, указывающий, что ваш скрипт уже запущен. Вы можете просто создать пустой .run
файл. Вам нужен только json (или рассольник, или, по крайней мере, явная запись файла), если вы хотите посчитать больше, чем просто «это первый раз, когда мой скрипт запускается», но вопрос по этому поводу был довольно ясен.
Но для любых более сложных сценариев потребуется json. Кроме того, моя интерпретация вопроса ОП заключается в том, как показать, сколько раз этот файл был выполнен, а не просто логическое значение того, был ли этот файл выполнен раньше или нет. Хотя я могу ошибаться, мое решение, тем не менее, добавляет дополнительную функциональность, которая обычно приветствуется.
Итак, вы знаете цену. Это логическое значение либо
True
, либоFalse
, основанное на хранении где-то информации о запуске. Python, конечно, не сделает этого за вас, это было бы очень странно (зачем ему считать, сколько раз его просили что-то запустить?) Самое простое решение — просто создать файл: если он не существует, первый забег. Если это так, то, очевидно, ваш скрипт уже выполнялся в прошлом. И умный программист создал бы файл конфигурации, который, если он не существует, создается с разумными настройками по умолчанию.