In this project, i was told to make a code where i should leverage the convenience of a dictionary to power a configuration file.
My following code looks like this:
class ConfigDict(dict):
def __init__(self, filename):
self._filename = filename
if os.path.isfile(self._filename):
with open(self._filename) as fh:
for line in fh:
line = line.rstrip()
key, value = line.split('=', 1)
dict.__setitem__(self, key, value)
def __setitem__(self, key, value):
dict.__setitem__(self, key, value)
with open(self._filename, 'w') as fh:
for key, val in self.items():
fh.write('{0}={1}\n'.format(key, val))
cd = ConfigDict("Config_file.txt")
The problem arises when i try to run the code, with the specified file name, An error of "ValueError: not enough values to unpack (expected 2, got 1)", from this line of code:
key, value = line.split('=', 1)
I have searched for solutions regarding this particular problem but have never seem to find it, and your help would really benefit me.
CodePudding user response:
First, it would be great if you could share a few sample lines from your input file.
The reason you get the error is because line.split('=', 1)
is not returning two values (key
and value
). What solution to go for depends on what you intend to do with the file.
If you are expecting only 2 values, then keep the code as is and check your files. I see you already leverage the maxsplit
argument, which determines the maximum times to split:
key, value = line.split("=", maxsplit=1).
This will not only ensure that only a single split is done but also that it returns a list with 2 elements (at most) or less. Less is the issue here since the line you are reading doesn't have that many. Could it be the headline or a line containing other info that cannot be parsed using split
? This is important because if you have any corrupt line with more than a single "=" symbol, then a ValueError will be thrown:
line = "1=2=3"
key, value = line.split("=")
> ValueError: too many values to unpack (expected 2)
And if you have less, then you will get the error you cited above.
If you have some corrupt lines with only <= 1 value to split, then a good course of action would be to ignore such lines altogether with a try/except block:
class ConfigDict(dict):
def __init__(self, filename):
self._filename = filename
if os.path.isfile(self._filename):
with open(self._filename) as fh:
for line in fh:
line = line.rstrip()
try:
key, value = line.split('=', 1)
dict.__setitem__(self, key, value)
except ValueError:
pass
The code above will only set key/value pairs if the split was successful.
Your code otherwise seems perfectly fine.
CodePudding user response:
This error is because of a corner case. Suppose line = 'apple'
, then key,value = line.split('=', 1)
will throw error.Your code is expecting two values but this corner case will return only one value hence the error "Value Error: not enough values to unpack (expected 2, got 1)".