这是糟糕的编程习惯,是的,我知道,但这些脚本纯粹是我的,这种技术可以简化我的编码。
现在,我有一个SQLite数据库,其中包含一组代表我脚本配置指令的键值对。脚本本身是一个我导入其他脚本的类。
所以,现在,当我想访问一个配置变量时,我会调用类似的东西:
myLib.myClass.getConfigVariable("theItemIWant")
在脚本中使用配置变量时,这非常难看。
所以我想简化对这些变量的访问。我可以使用一个字典,在加载类时预先填充并执行:
myLib.myClass.config['theItemIWant']
但我的想法更优雅。我写了一个单独的Config类,我想提供对配置条目的可变级访问。
所以我希望能做的是:
myLib.Config().theItemIWant
或者在脚本中实例化对象:
def myRoutine(self):
cfg = myLib.Config()
print cfg.theItemIWant
我已经读过关于丑陋(使用exec)的方法来实现这一点,我实际上对此很好,但我无法弄清楚如何以这种方式设置CLASS级变量。大多数人建议使用exec或改变变量或全局变量,但我不确定这是否会完成直接在Config类上设置变量而不是其他地方。
使用exec失败:
SyntaxError: unqualified exec is not allowed in function '__init__' it contains a nested function with free variables
所以我看到的唯一方法就是改变vars(),但我不确定这是如何适用于类的。
答案 0 :(得分:2)
您可以简单地为配置对象实现__getattr__()
函数,例如
def __getattr__(self, name):
if name in self.items:
return self.items[name]
else:
raise AttributeError()
有关python文档中__getattr__()
的说明,请参阅here。
答案 1 :(得分:2)
试图不重新发明轮子的解决方案。当你只想读取配置一次,它的结构是扁平的时候工作。
from collections import namedtuple
def getConfig(config_source):
# read the config_source into a dict
# config_source might be a file name or whatnot
config_dict = read_somehow(config_source)
tuple_class = namedtuple('Config', config_dict.keys())
return tuple_class(**config_dict)
该函数返回一个不可变对象,其属性以配置参数名称命名。
# suppose config file is something like:
# a = 1
# foo = bar
cfg = getConfig(...)
print cfg.a # prints 1
print cfg.foo # prints foo
print cfg.unknown # raises AttributeError
我曾经使用这种方法来阅读标准ConfigParser
实例中的部分。
答案 2 :(得分:1)
我认为你想要的只是分配给一个成员变量,如下所示:
class Foo(object):
pass
cfg = Foo()
cfg.item_i_want = "An item"
print cfg.item_i_want
这将打印“一个项目”。请参阅:http://ideone.com/LDz7NK
如果要动态选择变量名称,请使用setattr(cfg, "another_item_i_want", "another item")
。