2

クラスのクラスメソッドになるようにマジックメソッドを装飾しようとしてい__getitem__ます。これが私が試したサンプルです。クラスメソッドまたは静的メソッドの装飾を使用してもかまいませんが、その方法がよくわかりません。これが私が試したものです:

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

ただし、電話をかけようとするとSettings['database']、次のエラーが発生します。

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

誰が私が間違っているのか教えてもらえますか。また、これを行うためのより良い方法があるかどうか、誰かが提案できますか? MetaClasses を使用してみましたが、ほとんど成功しませんでした (Python がよくわからないため)。

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

 class Settings(object):
  __metaclass__ = Meta

前もって感謝します。

4

2 に答える 2

6

Python は常に__getitem__、インスタンスではなく、クラスの他の魔法のメソッドを検索します。したがって、たとえば、__getitem__メタクラスで a を定義すると、クラスにインデックスを付けることができます (ただし、存在しない in に委譲して定義することは__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

もちろん、それだけなら、このコードを「クラスにインデックスを付ける」ように設計するのはばかげているでしょう。クラスには、状態とメソッドを含むインスタンスもある方がよいでしょう。それ以外の場合は、代わりにモジュールをコーディングする必要があります。 -)。また、特定のインスタンスなどではなく、クラス全体にインデックスを付けることによって「適切な」アクセスを行う必要がある理由は明らかではありません。しかし、私はあなたがこのように物事を構造化したいという正当な設計上の理由を持っていると仮定して、あなたに賛辞を送り、そのような構造を実装する方法を示します;-)。

于 2010-07-21T15:56:35.220 に答える
1

アレックスの(完全に正しい)答えとは別に、ここで実際に何をしたいのかは明確ではありません。現在、クラスをインスタンス化するときに構成をロードしようとしています。その _config をクラス オブジェクトに割り当てると、クラスのすべてのインスタンスが同じ構成を共有することになります (別のインスタンスを作成すると、既存のすべてのインスタンスが最新の構成を指すように変更されます) クラスの特定のインスタンスではなく、この構成にアクセスするには? 構成が 1 つしかない場合でも、クラスのインスタンスを使用する方がはるかに便利です (そして理解しやすいです!)。このインスタンスをモジュールグローバルに保存して、必要に応じて「設定」と呼ぶこともできます:

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

Settings = _Settings('/path/to/config.ini')
于 2010-07-21T16:03:19.297 に答える