我试图将魔术方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import ConfigParser class Settings(object): _env = None _config = None def __init__(self, env='dev'): _env = env # find the file filePath ="C:\\temp\\app.config" #load the file _config = ConfigParser.ConfigParser() _config.read(filePath) @classmethod def __getitem__(cls, key): return cls._config.get(cls._env, key) @classmethod def loadEnv(cls, env): cls._env = env |
但是,当我尝试调用
1 2 3 | Traceback (most recent call last): File"<stdin>", line 1, in <module> TypeError: expected Array[Type], got str |
谁能告诉我哪里做错了吗?还有,有没有人能建议一下有没有更好的方法?我甚至尝试使用元类,但几乎没有成功(因为我对python不是很了解)。
1 2 3 4 5 6 | class Meta(type): def __getitem__(*args): return type.__getitem__(*args) class Settings(object): __metaclass__ = Meta |
提前谢谢。
Python总是在类上查找
因此,如果您需要索引一个类,比如
编辑:让我举一个简单的例子……
1 2 3 4 5 6 7 8 9 10 | >>> class MyMeta(type): ... def __getitem__(cls, k): ... return cls._config.get(k) ... >>> class Settings: ... __metaclass__ = MyMeta ... _config = dict(foo=23, bar=45) ... >>> print Settings['foo'] 23 |
当然,如果这就是全部内容,那么将这段代码架构为"索引一个类"将是愚蠢的——一个类最好也有带状态和方法的实例,否则您应该只编写一个模块;-)。为什么"正确"的访问应该通过索引整个类而不是一个特定的实例等等,这一点还远不清楚。但是,我要向您表示敬意,假设您有一个很好的设计理由想要以这种方式构造事物,并向您展示如何实现这样的结构;-)。
除了Alex的(完全正确的)答案之外,我们并不清楚您实际上想在这里做什么。现在,在实例化类时,尝试加载配置。如果将该_config分配给类对象,则意味着该类的所有实例共享相同的配置(创建另一个实例将更改所有现有实例以指向最新的配置)。为什么要使用类来访问这个配置,而不是类的特定实例?即使您只有一个配置,使用类的实例也要方便得多(而且可以理解!)你甚至可以将这个实例存储在模块全局中,如果你愿意,可以将它命名为"设置":
1 2 3 4 5 6 | class _Settings(object): def __init__(self, fname): self._config = ... ... Settings = _Settings('/path/to/config.ini') |