从变量设置类(自)变量?

时间:2013-05-01 17:23:49

标签: python variables

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

现在,我有一个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(),但我不确定这是如何适用于类的。

3 个答案:

答案 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")