@StaticMethod or @ClassMethod decoration on magic methods
I am trying to decorate the magic method __getitem__
to be a classmethod on the class. Here is a sample of what I tried. I don't mind using either classmethod or staticmethod decoration, but I am not too sure how to do it. Here is what I tried:
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
However, when I try to call Settings['database']
I get the following error.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: expected Array[Type], got str
Can anyone tell me what I am doing wrong. Also, could someone suggest if there is better way to do this? I even tried using MetaClasses, but with little success (as I don't know python too well).
class Meta(type):
def __getitem__(*args):
return type.__getitem__(*args)
class Settings(object):
__metaclass__ = Meta
Thanks in advance.
Apart from Alex's (entirely correct) answer, it isn't clear what you actually want to do here. Right now you are trying to load the config when you instantiate the class. If you were to assign that _config to the class object, that would mean all instance of the class share the same config (and creating another instance would change all existing instances to point to the latest config.) Why are you trying to use the class to access this configuration, instead of a particular instance of the class? Even if you only ever have one configuration, it's much more convenient (and understandable!) to use an instance of the class. You can even store this instance in a module-global and call it 'Settings' if you like:
class _Settings(object):
def __init__(self, fname):
self._config = ...
...
Settings = _Settings('/path/to/config.ini')
Python always looks up __getitem__
and other magic methods on the class, not on the instance. So, for example, defining a __getitem__
in a metaclass means that you can index the class (but you can't define it by delegating to a non-existent __getitem__
in type
-- just as you can never define anything by delegating to other non-existent methods, of course;-).
So, if you need to index a class such as Settings
, your custom metaclass must indeed define __getitem__
, but it must define it with explicit code that performs the action you desire -- the return cls._config.get
you want.
Edit : let me give a simplified example...:
>>> 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
Of course, if that was all there was to it, it would be silly to architect this code as "indexing a class" -- a class had better have instances with states and methods, too, otherwise you should just code a module instead;-). And why the "proper" access should be by indexing the whole class rather than a specific instance, etc, is far from clear. But I'll pay you the compliment of assuming you have a good design reason for wanting to structure things this way, and just show you how to implement such a structure;-).
链接地址: http://www.djcxy.com/p/9206.html