魔术方法上的@StaticMethod或@ClassMethod装饰

Bob*_*pra 1 python static-methods decorator magic-methods

我试图将魔术方法装饰__getitem__成课堂上的类方法.这是我尝试的样本.我不介意使用classmethod或staticmethod装饰,但我不太清楚如何做到这一点.这是我尝试过的:

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
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试调用时,Settings['database']我收到以下错误.

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: expected Array[Type], got str
Run Code Online (Sandbox Code Playgroud)

谁能告诉我我做错了什么.此外,有人可以建议是否有更好的方法来做到这一点?我甚至尝试过使用MetaClasses,但收效甚微(因为我不太了解python).

 class Meta(type):
  def __getitem__(*args):
   return type.__getitem__(*args)

 class Settings(object):
  __metaclass__ = Meta
Run Code Online (Sandbox Code Playgroud)

提前致谢.

Ale*_*lli 5

Python总是__getitem__在类上查找和其他魔术方法,而不是实例.因此,例如,定义__getitem__在元类意味着你可以索引(但你无法通过委托给一个不存在的定义它__getitem__type-就像你永远无法通过委托给其他不存在的方法定义了什么, 当然;-).

因此,如果您需要索引一个类,例如Settings,您的自定义元类必须确实定义__getitem__,但它必须使用显式代码来定义它,以执行return cls._config.get您想要的操作 - 您想要的.

编辑:让我举一个简单的例子......:

>>> 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
Run Code Online (Sandbox Code Playgroud)

当然,如果就是这样的话,那么将这段代码构建为"索引类"是很愚蠢的 - 一个类最好还有状态和方法的实例,否则你应该只编写一个模块代码; - ).为什么"适当的"访问应该通过索引整个类而不是特定的实例等,这一点远非明确.但是我会恭维你假设你有一个很好的设计理由想要以这种方式构建东西,并告诉你如何实现这样的结构;-).