I received a project from developer who left our company. Not too complex, but it doesn't look very nice.
So here is the question:
Application has some modules and one is "settings" which stores some app. options (not all possible options, lets say just two: foo
and bar
).
When application is started it reads options from command line (using argparse):
parser.add_argument('--foo', action='store_true')
parser.add_argument('--bar', action='store_true')
parser.add_argument('--baz', action='store_true')
And then it performs this nasty thing:
for name, val in parser.parse_args(sys.argv[1:])._get_kwargs():
setattr(sys.modules['settings'], name, val)
First: I think this is dirty, non-pythonic hack. And second, it is simply inconvenient to use such code, because when I need to use settings.baz
, IDE complaints that it doesn't exist.
The intention of this hack is to make options parsed from command line available in all modules that are used in application further.
I'm thinking about something like singleton pattern, but I only used it once in PHP, and don't know if this correct solution in python. And even if it is, can someone show example?
I'm noob in python and on SO, please be kind to me :) Thanks.
p.s. I'm sorry for possible mistakes in my English
App.config To access these values, there is one static class named ConfigurationManager, which has one getter property named AppSettings. We can just pass the key inside the AppSettings and get the desired value from AppSettings section, as shown below.
App. Config is an XML file that is used as a configuration file for your application. In other words, you store inside it any setting that you may want to change without having to change code (and recompiling). It is often used to store connection strings.
The configparser module has ConfigParser class. It is responsible for parsing a list of configuration files, and managing the parsed database. Return all the configuration section names.
Modules in Python are singleton objects, and using one to store the settings used by the other modules would be a very Pythonic
The second line of the "nasty thing" is just setting the attributes of a module named settings
and so isn't that bad. What's worse is the _get_kwargs()
part of the first line which is accessing a private attribute of the argparse.Namespace
object returned by parser.parse_args()
to get the names and values of the settings parsed from the command-line. A slightly better way to do it might be something like this:
import settings # possibly empty .py file
for name, val in vars(parser.parse_args(sys.argv[1:])).iteritems():
setattr(settings, name, val)
However this won't fix your IDE problems because the IDE doesn't know the name of settings added dynamically. A simple way to fix that would be to define all the possible attributes with some kind of default values in a settings.py
module instead of having an empty one.
The first time a module is import
ed an entry for it is added to the sys.modules
dictionary with its name as the key and an instance of types.ModuleType
as a value. Subsequent import
s will first check to see if an entry for it already exists and will skip reloading the file if it does -- which is why I claim they're basically singleton objects. Modifications made to its attributes will immediately be visible to other modules that have imported it or do so afterwards, so it's generally a good data sharing mechanism within an application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With