I'm using the Python module iniparse to save keys to an INI file, but I was wondering if there is a way to delete keys and sections from the INI file using iniparse. I know it's possible using ConfigParser and that iniparse is backwards compatible with ConfigParser, but I can't figure out how to perform the deletions using the same iniparse object.
from iniparse import INIConfig, RawConfigParser
cfg = INIConfig(open('options.ini'))
print cfg.section.option
cfg.section.option = 'new option'
# Maybe I need to use RawConfigParser somehow?
cfg.remove_option('section','option')
cfg.remove_section('section')
f = open('options.ini', 'w')
print >>f, cfg
f.close()
To remove a section or an option you simply need to delete it. Your revised code would be:
from iniparse import INIConfig
cfg = INIConfig(open('options.ini'))
print cfg.section.option
cfg.section.option = 'new option'
del cfg.section.option
del cfg.section
f = open('options.ini', 'w')
print >>f, cfg
f.close()
Note that if you want to delete a whole section you don't need to delete its options before: just delete the section.
Note also that this way of doing it feels more Pythonic than using remove_option and remove_section methods.
Related
Brand new to stack and python; hopefully someone wiser than myself can help. I have searched up and down and can't seem to find an actual answer to this, apologies if there is an exact answer and I've missed it :( (the few that I've found are either old or don't seem to work).
Closest I've found is
Best way to retrieve variable values from a text file?
Alas, imp seems to be depreciated and tried figuring out importlib but little above my current brain to figure out how to adapt it as errors throw up left and right on me.
This is very close to what I want and could potentially work if someone can help update with new methods, alas still doesn't have how to overwrite the old variable.
= - - Scenario - - =
I would like to create a preferences file (let's call it settings.txt or settings.py: doesn't need to be cross-compatible with other languages, but some reason I'd prefer txt - any preference/standards coders can impart would be appreciated?).
\\\ settings.txt\
water_type = "Fresh"\
measurement = "Metric"\
colour = "Blue"\
location = "Bottom"\
...
I am creating a script main_menu.py which will read variables in settings.txt and write to this file if changes are 'saved'
ie.
"select water type:"
Fresh
Salt
if water_type is the same as settings.txt, do nothing,
if water_type different, overwrite the variable in the settings.txt file
Other scripts down the line will also read and write to this settings file.
I've seen:
from settings import *
Which seems to work for reading the file if I go the settings.py path but still leaves me on how do I overwrite this.
also open to any better/standard/ideas you guys can think of.
Appreciate any help on this!
Here are some suggestions that may help you:
Use a json file:
settings.json
{
"water_type": "Fresh",
"measurement": "Metric",
"colour": "Blue",
"location": "Bottom",
...
}
then in python:
import json
# Load data from the json file
with open("settings.json", "r") as f:
x = json.load(f) # x is a python dictionary in this case
# Change water_type in x
x["water_type"] = "Salt"
# Save changes
with open("settings.json", "w") as f:
json.dump(x, f, indent=4)
Use a yaml file: (edit: you will need to install pyyaml)
settings.yaml
water_type: Fresh
measurement: Metric
colour: Blue
location: Bottom
...
then in python:
import yaml
# Load data from the yaml file
with open("settings.yaml", "r") as f:
x = yaml.load(f, Loader=yaml.FullLoader) # x is a python dictionary in this case
# Change water_type in x
x["water_type"] = "Salt"
# Save changes
with open("settings.yaml", "w") as f:
yaml.dump(x, f)
Use a INI file:
settings.ini
[Preferences]
water_type=Fresh
measurement=Metric
colour=Blue
location=Bottom
...
then in python:
import configparser
# Load data from the ini file
config = configparser.ConfigParser()
config.read('settings.ini')
# Change water_type in config
config["Preferences"]["water_type"] = "Salt"
# Save changes
with open("settings.ini", "w") as f:
config.write(f)
For .py config files, it's usually static options or settings.
Ex.
# config.py
STRINGTOWRITE01 = "Hello, "
STRINGTOWRITE02 = "World!"
LINEENDING = "\n"
It would be hard to save changes made to the settings in such a format.
I'd recommend a JSON file.
Ex. settings.json
{
"MainSettings": {
"StringToWrite": "Hello, World!"
}
}
To read the settings from this file into a Python Dictionary, you can use this bit of code.
import json # Import pythons JSON library
JSON_FILE = open('settings.json','r').read() # Open the file with read permissions, then read it.
JSON_DATA = json.loads(JSON_FILE) # load the raw text from the file into a json object or dictionary
print(JSON_DATA["MainSettings"]["StringToWrite"]) # Access the 'StringToWrite' variable, just as you would with a dictionary.
To write to the settings.json file you can use this bit of code
import json # import pythons json lib
JSON_FILE = open('settings.json','r').read() # Open the file with read permissions, then read it.
JSON_DATA = json.loads(JSON_FILE) # load the data into a json object or dictionary
print(JSON_DATA["MainSettings"]["StringToWrite"]) # Print out the StringToWrite "variable"
JSON_DATA["MainSettings"]["StringToWrite"] = "Goodnight!" # Change the StringToWrite
JSON_DUMP = json.dumps(JSON_DATA) # Turn the json object or dictionary back into a regular string
JSON_FILE = open('settings.json','w') # Reopen the file, this time with read and write permissions
JSON_FILE.write(JSON_DUMP) # Update our settings file, by overwriting our previous settings
Now, I've written this so that it is as easy as possible to understand what's going on. There are better ways to do this with Python Functions.
You guys are fast! I'm away from the computer for the weekend but had to log in just to say thanks.
I'll look into these more next week when I'm back at it and have some time to give it the attention needed. A quick glance could be a bit of fun to implement and learn a bit more.
Had to answer as adding comment only is on one of your guys solutions and wanted to give a blanket thanks to all!
Cheers
Here's a python library if you choose to do it this way.
If not this is also a good resource.
Creating a preferences file example
Writing preferences to file from python file
import json
# Data to be written
dictionary ={
"name" : "sathiyajith",
"rollno" : 56,
"cgpa" : 8.6,
"phonenumber" : "9976770500"
}
# Serializing json
json_object = json.dumps(dictionary, indent = 4)
# Writing to sample.json
with open("sample.json", "w") as outfile:
outfile.write(json_object)
Reading preferences from .json file in Python
import json
# open and read file content
with open('sample.json') as json_file:
data = json.load(json_file)
# print json file
print(data)
i'm writing a script in Python doing a while true cicle, how can I make my script take the same file abc123.json for each cicle and modify some variables in it?
If I understand your question correctly, you want to read a file named abc123.json somewhere on a local hard drive that is accessible via path and modify a value for a key (or more) for that json file, then re-write it.
I'm pasting an example of some code I used a while ago in hopes it helps
import json
from collections import OrderedDict
from os import path
def change_json(file_location, data):
with open(file_location, 'r+') as json_file:
# I use OrderedDict to keep the same order of key/values in the source file
json_from_file = json.load(json_file, object_pairs_hook=OrderedDict)
for key in json_from_file:
# make modifications here
json_from_file[key] = data[key]
print(json_from_file)
# rewind to top of the file
json_file.seek(0)
# sort_keys keeps the same order of the dict keys to put back to the file
json.dump(json_from_file, json_file, indent=4, sort_keys=False)
# just in case your new data is smaller than the older
json_file.truncate()
# File name
file_to_change = 'abc123.json'
# File Path (if file is not in script's current working directory. Note the windows style of paths
path_to_file = 'C:\\test'
# here we build the full file path
file_full_path = path.join(path_to_file, file_to_change)
#Simple json that matches what I want to change in the file
json_data = {'key1': 'value 1'}
while 1:
change_json(file_full_path, json_data)
# let's check if we changed that value now
with open(file_full_path, 'r') as f:
if 'value 1' in json.load(f)['key1']:
print('yay')
break
else:
print('nay')
# do some other stuff
Observation: the code above assumes that both your file and the json_data share the same keys. If they dont, your function will need to figure out how to match keys between data structures.
Is there a way to cache python file handles? I have a function which takes a netCDF file path as input, opens it, extracts some data from the netCDF file and closes it. It gets called a lot of times, and the overhead of opening the file each time is high.
How can I make it faster by maybe caching the file handle? Perhaps there is a python library to do this
Yes, you can use following python libraries:
dill (required)
python-memcached (optional)
Let's follow the example. You have two files:
# save.py - it puts deserialized file handler object to memcached
import dill
import memcache
mc = memcache.Client(['127.0.0.1:11211'], debug=0)
file_handler = open('data.txt', 'r')
mc.set("file_handler", dill.dumps(file_handler))
print 'saved!'
and
# read_from_file.py - it gets deserialized file handler object from memcached,
# then serializes it and read lines from it
import dill
import memcache
mc = memcache.Client(['127.0.0.1:11211'], debug=0)
file_handler = dill.loads(mc.get("file_handler"))
print file_handler.readlines()
Now if you run:
python save.py
python read_from_file.py
you can get what you want.
Why it works?
Because you didn't close the file (file_handler.close()), so object still exist in memory (has not been garbage collected, because of weakref) and you can use it. Even in different process.
Solution
import dill
import memcache
mc = memcache.Client(['127.0.0.1:11211'], debug=0)
serialized = mc.get("file_handler")
if serialized:
file_handler = dill.loads(serialized)
else:
file_handler = open('data.txt', 'r')
mc.set("file_handler", dill.dumps(file_handler))
print file_handler.readlines()
What about this?
filehandle = None
def get_filehandle(filename):
if filehandle is None or filehandle.closed():
filehandle = open(filename, "r")
return filehandle
You may want to encapsulate this into a class to prevent other code from messing with the filehandle variable.
I'm basically writing text to a file for example
data = ("save.data", "a+")
data.write(u"name = 'zrman'")
I wan't to be able to load that file and allow me to do this in python
print name
Any help would be great
-Thx
Use ConfigParser Python module. It's exactely what you're looking for.
Write :
import ConfigParser
config = ConfigParser.RawConfigParser()
config.set('main', 'name', 'zrman')
with open('conf.ini', 'wb') as configfile:
config.write(configfile)
Read :
from ConfigParser import ConfigParser
config = ConfigParser()
config.read('conf.ini')
print config.sections()
# ['main']
print config.items('main')
# [('name', 'zrman')]
Take a look at the docs here, this will walk you through the process of reading and writing files in python.
You could read in the lines and then exec the code:
f = open('workfile', 'w')
for line in f:
exec(line)
print name
So, I have this settings.ini :
[SETTINGS]
value = 1
And this python script
from ConfigParser import SafeConfigParser
parser = SafeConfigParser()
parser.read('settings.ini')
print parser.get('SETTINGS', 'value')
As you can see, I want to read and then replace the value "1" by another one. All I was able to do so far is to read it. I searched on the net how to replace it but I didn't find.
As from the examples of the documentation:
https://docs.python.org/2/library/configparser.html
parser.set('SETTINGS', 'value', '15')
# Writing our configuration file to 'example.ini'
with open('example.ini', 'wb') as configfile:
parser.write(configfile)
Python's official docs on configparser illustrate how to read, modify and write a config-file.
import configparser
config = configparser.ConfigParser()
config.read('settings.ini')
config.set('SETTINGS', 'value','15')
with open('settings.ini', 'w') as configfile:
config.write(configfile)
I had an issue with:with open
Other way:
import configparser
def set_value_in_property_file(file_path, section, key, value):
config = configparser.RawConfigParser()
config.read(file_path)
config.set(section,key,value)
cfgfile = open(file_path,'w')
config.write(cfgfile, space_around_delimiters=False) # use flag in case case you need to avoid white space.
cfgfile.close()
It can be used for modifying java properties file: file.properties
Below example will help change the value in the ini file:
PROJECT_HOME="/test/"
parser = ConfigParser()
parser.read("{}/conf/cdc_config.ini".format(PROJECT_HOME))
parser.set("default","project_home",str(PROJECT_HOME))
with open('{}/conf/cdc_config.ini'.format(PROJECT_HOME), 'w') as configfile:
parser.write(configfile)
[default]
project_home = /Mypath/