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

我试图装饰魔法__getitem__成为课堂上的一个classmethod。 这是我尝试过的一个例子。 我不介意使用classmethod或staticmethod装饰,但我不太确定如何去做。 这是我试过的:

import ConfigParser

class Settings(object):
   _env = None
   _config = None

   def __init__(self, env='dev'):
    _env = env
    # find the file
    filePath = "C:tempapp.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

但是,当我尝试调用Settings['database'] ,出现以下错误。

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

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

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

 class Settings(object):
  __metaclass__ = Meta

提前致谢。


除了亚历克斯(完全正确)的答案之外,目前还不清楚你实际想在这里做什么。 现在你正试图在实例化类时加载配置。 如果将_config分配给类对象,那意味着该类的所有实例都共享相同的配置(并且创建另一个实例会将所有现有实例更改为指向最新配置​​。)为什么要尝试使用该类访问此配置,而不是该类的特定实例? 即使你只有一个配置,使用该类的实例也会更方便(也是可以理解的!)。 您甚至可以将此实例存储在模块全局中,如果您愿意,可以将其称为“设置”:

class _Settings(object):
    def __init__(self, fname):
        self._config = ...
    ...

Settings = _Settings('/path/to/config.ini')

Python总是在类上查找__getitem__和其他魔术方法,而不是在实例上。 因此,例如,在元类中定义__getitem__意味着您可以对类进行索引(但您无法通过委托给type不存在的__getitem__来定义它 - 就像您永远无法通过委派给其他非当然存在的方法;-)。

因此,如果您需要为类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

当然,如果这就是它的全部,那么把这个代码设计为“索引一个类”会很愚蠢 - 一个类最好有状态和方法的实例,否则你应该只编写一个模块; - )。 为什么“适当”的访问应该是通过索引全班而不是具体实例等等,这是远远不明确的。 但是,我会向你致敬,假设你有一个好的设计理由,希望以这种方式构造事物,并告诉你如何实现这样的结构;-)。

链接地址: http://www.djcxy.com/p/9205.html

上一篇: @StaticMethod or @ClassMethod decoration on magic methods

下一篇: What are Class methods in Python for?