0

DBスキーマのポリモーフィズムの一部であるクラスがたくさんあります。それらのほとんどで私は(する必要があります)します:

__mapper_args__ = {'polymorphic_identity': unique_integer}
# unique_integer is a unique integer different for each class ex: 10

これの代わりに、デコレータを使用したいと思います。

@polid(10)
class ClassName(Inherited):
    # instead of repeating for each class the following:
    # __mapper_args__ = {'polymorphic_identity': 10}
    # I would like to have above decorator or something to do the trick.
    pass

これどうやってするの?どのようなデコレータを使用する必要がありますか?以下は機能しません(登録されません):

def polid(v):
    def x(f):
        f.__mapper_args__ = {'polymorphic_identity': v}
        return f
    return x
4

4 に答える 4

2

mixinを使用します。通常、それらは悪夢のようなものですが、宣言型クラスに共通の状態を注入することは合理的な使用法のように思えます。

class PolyMixin(object):
    __mapper_args__ = {'polymorphic_identity': 10}

class SomeTable(Base, PolyMixin):
    __tablename__ = "something"

class SomeOtherTable(Base, PolyMixin):
    __tablename__ = "something_else"
于 2013-02-27T00:34:10.807 に答える
1

おそらく、これまでに達成された、もう少し優れた、魔法の少ない解決策は次のようになります。

def PID(value):
    ''' Mixin Class Generator For Polymorphic Identity Inheritance '''
    class MixinClassForPolymorphicIdentityInheritance: 
        __mapper_args__ = {'polymorphic_identity': value}
    return MixinClassForPolymorphicIdentityInheritance

使用法:

class InheritingClass(PID(pidv), Parent): pass

(不幸にも)

于 2013-02-28T11:06:29.133 に答える
1

クラスが構築された後にクラスを変更しようとするため、デコレータは機能しません。その時点で、マッパーはすでにセットアップされています。

def polid(value):
    return type("mixinclass", (object,), {"__mapper_args__": {'polymorphic_identity': value}})

class ClassName(polid(10), Inherited):
    pass

これにより、必要なカスタム マッパー引数を使用して、polid が呼び出されるたびに新しいクラスが作成されます。

于 2013-02-27T02:08:11.423 に答える
0

メタクラス アプローチの何が問題なのですか?

class PolyMeta(DeclarativeMeta):
    def __new__(cls, clsname, bases, namespace, value=None, **kwargs):
        if value is not None:
            namespace['__mapper_args__'] = dict(polymorphic_identity=value)
        return super().__new__(cls, clsname, bases, namespace, **kwargs)

class Inherited(Base, metaclass=PolyMeta): ...

class ClassName(Inherited, value=10): ...

もちろん、Py2 ではメタクラスに情報を通知する別の方法を見つける必要がありますが、それはレガシー言語を使用するために支払う代償です。:-P ただし、それほど難しいことではありません: 特別な属性_valueを使用するか、クラス名を値にマッピングする外部辞書を作成するか、値を記憶する架空の「ベース」を作成して、記述できるようにすることもできます

class ClassName(Inherited, Value(10)): ...

実際、最後のアプローチが最善だと思います (まだ Py2 に行き詰まっている場合)。ヘルプが必要な場合は、質問してください。書き出すようにします。

于 2015-07-18T14:19:01.330 に答える