1

以下の「何か」からサブクラス化された多数のクラスを作成しているプロジェクトの一部と統合することがわかった例から何かに従ってください。毎回それらをすべて書き出すこと (アイテムの数が大きくなり、属性のより小さなリストを渡すことで多くのボイラープレートを減らすことができるため、少なくとも要点です)。

とにかく、与えられた:

class SomethingMeta(type):
    def __init__(cls, name, bases, dct):
        if not hasattr(cls, 'registry'):
            cls.registry = {}
        else:
            interface_id = name.lower()
            cls.registry[interface_id] = cls

        super(SomethingMeta, cls).__init__(name, bases, dct)

class Something(object):
    __metaclass__ = SomethingMeta

class SomethingA(Something):
    def __init__(self, x, y):
        self.x = x
        self.y = y

 class SomethingB(Something):
    def __init__(self, z=0):
        self.z = z

そのため、「Something」を使用して作成されたクラスの Something.registry にレジストリがあります...しかし、私が本当にやりたいのは、「SomethingMeta」の「Something」サブクラス化クラスの属性のリストを取得することです。したがって、Something.registry では、登録されたサブクラスの属性、特定のサブクラスの属性をキャプチャする必要があります。サブクラス化されたクラスをディクショナリに入力します。私だけが今必要なものをきちんと突くことができないようです。

入力を歓迎し、明確化を提供できます。間違っている場合は、正確に何をしようとしているのかを教えてください。

編集:

結果を望んだ。全体的に私はしたいです:

1) サブクラス化されたインスタンスに必要な変数の dict を渡します (例: {'x': 1, 'y': 2})。

2) この dict からキーを取得し、一意の識別子/ハッシュを作成します (例: 34523sdfgsdg3423234234)。

3) その識別子が存在する場合は、Something.registry からそのサブクラスを取得し、そのサブクラスからインスタンスをインスタンス化するか、新しいサブクラスを作成し、それをレジストリに格納してそのインスタンスを返します。たとえば、Something.registry は {'34523sdfgsdg3423234234': }

多くのサブクラス化されたアイテムの主な際立った特徴は、それらが運ぶ情報であり、それらはすべて、それらが運ぶ他の情報に基づいてさまざまな方法で運ぶ情報で異なることを行いますが、サブクラス化されたクラスのメソッドにはすべて共通です。情報ペイロードに基づいてキーを作成しようとしているだけなので、冗長なコードを削除する自動生成の作業を開始できます。何かを理解できると思います。

4

1 に答える 1

0

のコードはSomethingMeta.__init__、クラスSomething(またはそのサブクラス) が定義されたときに実行されます。

のインスタンスの属性は、Somethingインスタンスがインスタンス化されたときにのみ定義されます。これは、かなり後で発生するか、まったく発生しない可能性があります。

そのため、レジストリはインスタンスを調べて、インスタンスが持つ可能性のある属性を見つけることができません。

しかし、すべての属性が の呼び出しシグネチャにリストされていることを保証できる場合はcls.__init__、 を使用inspect.getargspecして属性名を見つけることができます。

import inspect
class SomethingMeta(type):
    def __init__(cls, name, bases, dct):
        if not hasattr(cls, 'registry'):
            cls.registry = {}
        else:
            interface_id = name.lower()
            attrs, varargs, varkw, defaults = inspect.getargspec(cls.__init__)
            cls.registry[interface_id] = [a for a in attrs 
                                          if a not in ('self', None)]

        super(SomethingMeta, cls).__init__(name, bases, dct)

class Something(object):
    __metaclass__ = SomethingMeta

class SomethingA(Something):
    def __init__(self, x, y, *args, **kw):
        self.x = x
        self.y = y

class SomethingB(Something):
    def __init__(self, z=0):
        self.z = z

print(Something.registry)

収量

{'somethingb': ['z'], 'somethinga': ['x', 'y']}
于 2013-03-28T17:07:17.600 に答える