2

这是一种糟糕的编程习惯,是的,我知道,但是这些脚本纯粹是我的,这种技术可以大大简化我的编码工作。

现在,我有一个 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 或更改 vars 或 globals,但我不确定这是否会直接在 Config 类而不是其他地方设置变量。

使用 exec 失败:

SyntaxError: unqualified exec is not allowed in function '__init__' it contains a nested function with free variables

所以我看到的唯一方法是改变 vars() 但我不确定这如何适用于类。

4

3 回答 3

2

您可以简单地__getattr__()为您的配置对象实现该功能,例如

def __getattr__(self, name):
    if name in self.items:
         return self.items[name]
    else:
         raise AttributeError()

有关python 文档中的描述,请参见此处。__getattr__()

于 2013-05-01T17:32:42.577 回答
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实例中读取部分。

于 2013-05-01T18:23:55.813 回答
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").

于 2013-05-01T17:31:12.353 回答