0

さまざまな「ツール」を表す一連のクラスがあり、それぞれに ID キー、説明、タイトル、その他の定数があります。これらはすべて「GenericTool」クラスからサブクラス化されています。

すべてのサブクラスの ID を基に辞書を作成する方法が必要です。これにより、ID を指定して定数を簡単に検索できますが、中央の辞書を維持する必要はありません。

たとえば、ファイルtools/toola.py

import generic_tool as GT
class ToolA(GT.GenericTool):

    title = "Tool A"
    id = "tool_a"

ファイルtools/toolb.py

import generic_tool as GT
class ToolB(GT.GenericTool):

    title = "Tool B"
    id = "tool_b"

私はこのような辞書で終わりたいと思います:

{ 'tool_a': {'title': 'Tool A'},
  'tool_b': {'title': 'Tool B'} }

メタクラスの使用とスーパークラスのコードを調べました__init__()が、これらはクラスの実行時の作成に影響を与えるようですが、モジュールが最初にインポートされたときに一度だけ行うことに関心があります。

4

2 に答える 2

1

「中央辞書を維持する必要がない」ということは、「手動で更新された辞書を維持する必要がない」ことを意味すると仮定すると、これに対する解決策はメタクラスを使用することです。generic_tool.GenericToolこれには、次のように を定義する必要があります。

class GenericToolMeta(type):
    """Meta classs that is used by Tools to register in a central dictionary."""
    tools = {}

    def __new__(meta, classname, bases, classDict):
        new_class = type.__new__(meta, classname, bases, classDict)

        try:
            meta.tools[new_class.id] = new_class.title
        except AttributeError:
            pass
        return new_class

class GenericTool(object):
    __metaclass__ = GenericToolMeta

ベース ( ) または派生で直接__metaclass__宣言を使用する場合、クラス自体は定義時に自動的に登録されます (つまり、呼び出し時にインポート時):GenericToolTools

$ python
Python 2.7.3 (default, Jan  2 2013, 13:56:14) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import generic_tool
>>> generic_tool.GenericToolMeta.tools
{}
>>> import toola
>>> generic_tool.GenericToolMeta.tools
{'tool_a': 'Tool A'}
>>> import toolb
>>> generic_tool.GenericToolMeta.tools
{'tool_a': 'Tool A', 'tool_b': 'Tool B'}
>>> 
于 2013-04-28T22:34:00.797 に答える
1

メタクラス:

class GenericToolMeta(type):
    tool_dict = {}

    def __init__(cls, name, bases, dct):
        tool_dict[cls.id] = {'title': cls.title}
        super(GenericToolMeta, cls).__init__(name, bases, dct)
import generic_tool as GT
class ToolB(GT.GenericTool, metaclass=GT.GenericToolMeta):
    title = "Tool B"
    id = "tool_b"

またはデコレータを使用する場合:

tool_list = []

def tool(title, id):
    def decorator(cls):
        cls.title = title
        cls.id = id
        tool_list[id] = title
        return cls

    return decorator
import generic_tool as GT

@GT.tool(id="tool_b", title="Tool B")
class ToolB(GT.GenericTool):
    # ...
于 2013-04-28T22:30:42.107 に答える