0

Just hear me out:

I want to pass some arguments to a script from bash: python my_python_script.py set_api <api_key> but I want the api_key to be stored as a permanent variable inside the same script. I'm wondering if that's possible, since I have in mind other options, like I can simply store the variable inside a different file and make sure my script reads that file before anything else.

What is the best/safest approach?

Deneb
  • 981
  • 2
  • 9
  • 25
  • 2
    What do you mean by "permanent variable" (which seems oxymoronic!)? Do you want the command line call to *change* the contents of the `.py` file? – jonrsharpe Dec 21 '13 at 10:29
  • @jonrsharpe I know. Yes, that's what I want. – Deneb Dec 21 '13 at 10:29
  • Sure. Python doesn't lock the source file or otherwise prevent modifying it. The change just doesn't take place before you re-run the script. Another question is if this is a good way to solve the problem (and the answer is no). – JJJ Dec 21 '13 at 10:41

3 Answers3

5

While the method of modifying your source file mentioned by others would probably work, I would highly recommend looking into other solutions such as storing a configuration file with the relevant information that is changing. If you don't want to write this functionality yourself (which can be as simple as a hidden file in the same directory as the script with a single line containing, say, an api key) you can look into solutions such as ConfigParser, using JSON, or even just pickling an object. When you need to access that information, such as the value of an API key, you can read in the configuration file.

In general, if you need to reference something by a value look into using dictionaries. For instance, if my api key was "abc", instead of accessing foo.abc, I could put a dictionary d = {"abc": value} on foo and access foo.d["abc"]

Again, as mentioned by others, it is generally considered bad practice to write self-modifying code since it can be very hard to read and maintain. If you have the ability to write to the directory with the code file in it, there are rarely good reasons to modify that file over using a configuration/persistent state file.

FuegoFro
  • 3,867
  • 2
  • 18
  • 14
0

It is theoretically possible to have you program change its own source code. All you have to do is open the file for writing and write the desired data into it. As discussed here, you can't actually insert data into a file, so you'll basically need to pass the entire source code plus the assignment of the new api_key value into file.write(), which will be pretty cumbersome, particularly if your code is complex. This is one of the many reasons that this is a risky and not-super-elegant solution. If you want to play around with it anyway, I definitely recommend backing up your original code somewhere.

Community
  • 1
  • 1
seaotternerd
  • 6,298
  • 2
  • 47
  • 58
0

You try to do something like this:

def store(const_name, value):
    import re
    with open(__file__, 'r') as f:  # read source of this script
        content = f.read()
        changed = re.replace('^'+const_name+'.*$', const_name + ' = '+ str(value))
    with open(__file__, 'w') as f:  # write source of this script
        f.write(changed)

This methods are unsafe and you shall not use it in real life because someone may corrupt your script or change it to do evil things.

akaRem
  • 7,326
  • 4
  • 29
  • 43