1

I was not sure how to phrase this question's title.

Is there a method in Python that would take input from the terminal and write that input into the script and save that change? In other words the script would be self updating. The user enters some sequence of characters at the prompt and the script would write those characters into the body of the script. The next time the script is executed those character will be available for reference.

brett
  • 198
  • 3
  • 9

2 Answers2

3

You could rewrite the source file, yes. It's just a file, and reading and writing files is perfectly doable in Python. Python loads source files just once, so re-writing them is certainly possible.

But it'd be much easier to just use a separate file to write the sequence, and read it back from that file next time you run your code.

Python has any number of data persistence modules that can help making reading and writing a sequence in files easier. Or you can re-use data serialization standards such as JSON to handle the reading and writing for you. These would be much easier to maintain.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • So during the script execution the script can modify and save itself? How is this done? I really need this change to occur in the script and not rely on a separate file. – brett Jan 01 '14 at 15:40
  • @brett: `__file__` is the filename of the source file or the bytecache; you can use this global to find the original source file and read it into your script. Python reads the file **once** when first importing the file (on start-up for the main script), so you can write a new version for the next time Python starts. – Martijn Pieters Jan 01 '14 at 15:41
  • @brett: but **why** do you need the change to occur in the script? What is your usecase? – Martijn Pieters Jan 01 '14 at 15:42
  • The script prompts the user for a user defined file name and creates that file. The next time the user executes, the script should look for the unique file (exists), if true, move on, if not prompt the user to point the script to the file or create a new file. So if the original file name was written to the script that would be nice. – brett Jan 01 '14 at 15:50
  • @brett: And you cannot write a **separate** file with the filename? That separate file would have a known filename, hardcoded in your script. You can use `os.path.dirname(os.path.abspath(__file__))` to get the directory path where your script currently lives, for example, and use that to get an absolute path to a new file right next to your script: `filename_file = os.path.join(current_directory, '.secret_filename_file.txt')` and write your data there. – Martijn Pieters Jan 01 '14 at 15:51
  • okay ... I will give that approach a try. Logically if my script relies on the existence of a user named created file (in the same directory) then it would be okay to have a file containing that file name. And that file, secret_fname_file.txt, can be updated when the other file name is changed or lost or whatever. Let me give that a go, thanks. – brett Jan 01 '14 at 16:04
0

The following script begins with lines 2 and 3 containing no file names -

#! /usr/bin/env python3
#
#
import os.path
no_file_1, no_file_2 = False, False
#open the file containing this script and read, by line, into list 'a', close this file
thisfile = open('__file__','r')
a = []
while True:
    file_line = thisfile.readline()
    if not file_line:
        break
    else:
        a.append(file_line)
thisfile.close()
#extract the file names from line 2 and 3 of this file (one file name per line)
file_1, file_2 = a [1], a [2]
file_1, file_2 = file_1[1:-1], file_2[1:-1]
#if there are no file(s) listed in line 2 and 3, prompt the user for file name(s)
#and write the file name(s) w/ extenstion '.txt' to a[1] and a[2]
if file_1 == '':
    no_file_1 = True
if file_2 == '':
    no_file_2 = True
if no_file_1:
    file_1 = input('Enter 1st File Name (no extension) >>> ')
    a [1] = '#' + file_1 + '.txt' + '\n'
if no_file_2:
    file_2 = input('Enter 2nd File Name (no extension) >>> ')
    a [2] = '#' + file_2 + '.txt' + '\n'
#... then write a[new script] to this script
if no_file_1 or no_file_2:
    thisfile = open(__file__, 'w')
    for i in a:
        thisfile.write(i)
#now that this script contains file names in lines 2 and 3, check to see if they exist
#in the same directory as this script ... if not, create them.
file_1, file_2 = a [1], a [2]
file_1, file_2 = file_1[1:-1], file_2[1:-1]
if not os.path.exists(file_1):
    open(file_1, 'w')
    #write to file_1.txt
if not os.path.exists(file_2):
    open(file_2, 'w')
thisfile.close()
print(file_1,file_2)

The script is executed, checks for and finds no file names in lines 2 and 3. The user enters two file names and the script overwrites itself with the correct file names, checks to see if the two files exist, if not, the script creates them.

Enter 1st File Name (no extension) >>> file_1
Enter 2nd File Name (no extension) >>> file_2

The next time the script is executed, the file names are defined in lines 2 and 3 and the script checks to see if they exist, if not, the script creates them.

#! /usr/bin/env python3
#file_1.txt
#file_2.txt
import os.path
no_file_1, no_file_2 = False, False
#open the file containing this script and read, by line, into list 'a', close this file
thisfile = open(__file__,'r')
a = []
while True:
    file_line = thisfile.readline()
    if not file_line:
        break
    else:
        a.append(file_line)
thisfile.close()
#extract the file names from line 2 and 3 of this file (one file name per line)
file_1, file_2 = a [1], a [2]
file_1, file_2 = file_1[1:-1], file_2[1:-1]
#if there are no file(s) listed in line 2 and 3, prompt the user for file name(s)
#and write the file name(s) w/ extenstion '.txt' to a[1] and a[2]
if file_1 == '':
    no_file_1 = True
if file_2 == '':
    no_file_2 = True
if no_file_1:
    file_1 = input('Enter 1st File Name (no extension) >>> ')
    a [1] = '#' + file_1 + '.txt' + '\n'
if no_file_2:
    file_2 = input('Enter 2nd File Name (no extension) >>> ')
    a [2] = '#' + file_2 + '.txt' + '\n'
#... then write a[new script] to this script
if no_file_1 or no_file_2:
    thisfile = open(__file__, 'w')
    for i in a:
        thisfile.write(i)
#now that this script contains file names in lines 2 and 3, check to see if they exist
#in the same directory as this script ... if not, create them.
file_1, file_2 = a [1], a [2]
file_1, file_2 = file_1[1:-1], file_2[1:-1]
if not os.path.exists(file_1):
    open(file_1, 'w')
    #write to file_1.txt
if not os.path.exists(file_2):
    open(file_2, 'w')
thisfile.close()
print(file_1,file_2)
brett
  • 198
  • 3
  • 9