本文介绍了如何跨模块存储应用程序设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我收到了离开我们公司的开发者的一个项目。不太复杂,但看起来不太好。
所以这里是一个问题:
应用程序有一些模块,一个是存储一些应用程序的设置。选项(并非所有可能的选项,可以说只有两个: foo
和 bar
)。
当应用程序启动时,它从命令行读取选项(使用argparse):
parser.add_argument(' foo',action ='store_true')
parser.add_argument(' - bar',action ='store_true')
parser.add_argument(' - baz',action ='store_true')
然后执行这个令人讨厌的事情:
<$ ()。$ get_kwargs():
setattr(sys.modules ['settings'],name,val
)
第一:我觉得这很脏,非pythonic破解。其次,使用这种代码简直不方便,因为当我需要使用 settings.baz
时,IDE抱怨它不存在。
这个破解的目的是让进一步在应用程序中使用的所有模块中的命令行解析选项。
我正在考虑类似单例模式,但我只在PHP中使用它一次,并不知道这是否正确的解决方案在Python。即使是这样,有人可以展示例子吗?
我是python和so的noob,请善待我:)
谢谢。 / p>
ps对于我的英语中可能出现的错误,我深表歉意。
Python中的模块是单独的对象,使用其中一个来存储其他模块使用的设置将是一个非常Pythonic
nasty thing的第二行是设置一个名为设置
,所以没那么糟糕。更糟糕的是,第一行访问 argparse.Namespace
对象的私有属性的 _get_kwargs()
部分由 parser.parse_args()
返回以获取从命令行解析的设置的名称和值。稍微好一些的方法可能是这样的:
导入设置#可能为空.py文件
for name,val in vars(parser.parse_args(sys.argv [1:]))。iteritems():
setattr(settings,name,val)
然而,这并不能解决您的IDE问题,因为IDE不知道动态添加的设置的名称。解决这个问题的一个简单方法是在 settings.py
模块中定义所有可能的具有某种默认值的属性,而不是一个空的属性。
$ b
第一次模块是 import
时,它的一个入口被添加到 sys.modules
字典,其名称为键, types.ModuleType
为实例。后续的 import
s将首先检查它的条目是否已经存在,如果它存在,将跳过重新加载文件 - 这就是为什么我声称它们基本上是单例对象。对其属性所做的修改将立即对其他已导入或之后这样做的模块可见,所以它通常是应用程序内的良好数据共享机制。
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
解决方案
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.
这篇关于如何跨模块存储应用程序设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!