I'm trying to make changeable variables in text files that are separate from my code module thing. So like when I run the module and add to the variables it will change it in the text file.
① Using ConfigParser
The simplest way to store a variable (or a value) is to use a .ini
file for storing configuration values. To store values:
>>> import configparser
>>> config = configparser.RawConfigParser()
>>> config.add_section('default')
>>> config.set('default', 'gold', '10')
To read values:
>>> with open('example.cfg', 'w') as configfile:
... config.write(configfile)
...
>>>
>>> config = configparser.RawConfigParser()
>>> config.read('example.cfg')
['example.cfg']
>>> gold = config.getint('default', 'gold')
>>> print(gold)
10
But then you might not like the output:
% cat example.cfg
[default]
gold = 10
② Using JSON
So then you might prefer to use JSON to do the same:
>>> config = dict(gold=10)
>>> json.dump(config, open('example.json', 'w'))
>>> import json
And to load it you do:
>>> import json
>>> config = json.load(open('example.json'))
>>> print(config)
{'gold': 10}
Now, you might be unhappy about it being a dict
. But you can make it a variable within a function, using the **
argument passing trick:
>>> def show_gold(gold):
... print("I got {}g of gold!".format(gold))
...
>>> show_gold(**config)
I got 10g of gold!
Even though I recommend you to do the former solution, if you really want to load it as a variable within the global scope, you can do:
>>> globals().update(config)
>>> print(gold)
10
③ Using pickle
Using pickle, you're having the same issue, you need to embed your data into something, or you won't have python remember the variable's name:
>>> import pickle
>>> gold = 10
>>> pickle.dump(gold, file=open('example.data', 'wb'))
>>> pickle.load(open('example.data', 'rb'))
10
So you'd better do:
>>> config = dict(gold=10)
>>> pickle.dump(config, file=open('example.data', 'wb'))
>>> pickle.load(open('example.data', 'rb'))
{'gold': 10}
and you can use the same tricks as shown earlier. Though, the main difference with pickle, is that it's using a binary file format, making it more flexible and faster to store complex and/or big python instances:
% od -cx example.data
0000000 200 003 } q \0 X 004 \0 \0 \0 g o l d q 001
0380 717d 5800 0004 0000 6f67 646c 0171
0000020 K \n s .
0a4b 2e73
0000024
So if you want to dump and restore nicely a value using pickle you can use an object's instance:
>>> import pickle
>>> class Foo:
... def __init__(self):
... self.gold = 10
...
>>> foo = Foo()
>>>
>>> pickle.dump(foo, open('example.data', 'wb'))
>>> bar = pickle.load(open('example.data', 'rb'))
>>> bar.gold
10
so, basically, the pickle
module is nice, but not suited for your usage, as you want to be able to read and modify the file manually.
Conclusion
I'd advice you to use the json
to serialise and deserialise data from your application, as the output is concise, elegant, thus easy to read. I have a preference over PyYaml, which looks even better when you need to edit manually. And the more commonly used serialiser is ConfigParser
, which is why this is the one I showed first. But you don't want to use pickle
which is very nice, but uses a binary format that you cannot change with an editor.
HTH