1
\$\begingroup\$

I am writing a Model to read, write and store settings. I think my code is pretty good, but I am not 100% sure. Any advice on how I could possibly improve it is welcome.

import ntpath
import yaml
class Settings:
 def __init__(self, paths=None, default_path=None):
 """Load, write and store settings
 This model manages setting files (YAML).
 Keyword Arguments:
 paths {list or None} -- list of full or relative
 paths with filenames (default: {None})
 default_path {str or None} -- path to user settings, read last
 and default for writing
 (default: {None})
 """
 paths = paths or []
 # Make sure paths are unique and sorted by file name
 self.paths = sorted(set(paths), key=lambda p: ntpath.basename(p))
 # Remove default_path from paths (look at next comment)
 try:
 self.paths.remove(default_path)
 except ValueError:
 pass
 # Readd default_path at the end to make sure it's loaded last
 if default_path is not None:
 self.paths.append(default_path)
 # Set remaining attributes
 self.default_path = default_path
 self.settings = {}
 # Load files
 self.reload()
 def reload(self):
 """Reload files into buffer
 Reloads the files specified in self.paths
 and writes them into the buffer.
 """
 # Clear settings to ensure no unwanted leftovers
 self.settings.clear()
 # Load every path (sorted by filename, self.default_path last)
 for path in self.paths:
 with open(path, 'r') as f:
 content = f.read()
 self.settings.update(yaml.load(content) or {})
 def write(self, key, value, path=None):
 """Write into file
 Writes key and value into the file specified
 by path (or self.default_path if None)
 Arguments:
 key {immutable} -- key to use (valid YAML key)
 value {ANY} -- value to save
 Keyword Arguments:
 path {str} -- path to save file (default: {None})
 """
 path = path or self.default_path
 assert path is not None
 with open(path, 'r') as f:
 settings = yaml.load(f.read()) or {}
 settings[key] = value
 self.settings[key] = value
 with open(path, 'w') as f:
 f.write(yaml.dump(settings, default_flow_style=False))
asked Jun 3, 2016 at 9:09
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

One thing I found so far is to either rename the attribute "settings" to "buffer" (or something similar), or to make Settings inherit from dict (or better from collections.MutableMapping as suggested here). Doing something like this is awkward:

settings_instance.settings['test_key']
answered Jun 3, 2016 at 10:03
\$\endgroup\$
1
\$\begingroup\$

The module should import os.path instead of ntpath.

os.path is the cross-platform equivalent of ntpath, it automatically picks the appropriate path module for the OS your code is running on. So it will use ntpath behind the scenes when running on Windows, but you will also be able to use the code on more operating systems than just Windows. (See the note at https://docs.python.org/3/library/os.path.html)

answered Jun 3, 2016 at 11:07
\$\endgroup\$
2
  • \$\begingroup\$ Thank you, I did it that way initially but changed it after reading the accepted answer to this post: stackoverflow.com/questions/8384737/…; Seems as he was wrong? \$\endgroup\$ Commented Jun 3, 2016 at 11:33
  • \$\begingroup\$ @Matthias: That post is dealing with Windows paths specifically. If you must deal with Windows paths, use ntpath; if you are dealing with whatever paths are used by the OS your program is run on, use os.path. You shouldn't be dealing with only Windows paths because you try to open the files. On Linux, you can't open Windows files. Therefore, you should be using os.path \$\endgroup\$ Commented Jun 3, 2016 at 13:13

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.