2017-06-12 9 views
0

私はgraphene.ObjectTypeサブクラスのメタクラスを作成しようとしています。私の主な目的は、名前を含む文字列のリストからクラスの属性(つまりGraphene Objectのフィールド)を作成することです。グラフェンでメタクラスを使用する際のエラー

たとえば、このリストは​​

、私のクラスAttack必見の何かが、このようなこと:

class Attack(graphene.ObjectType): 
    quantity = graphene.String() 
    position = graphene.String() 

次のように私はこれをやっている方法は次のとおりです。

import graphene 
from graphene.types.objecttype import ObjectType, ObjectTypeMeta 

class mytype(ObjectTypeMeta): 
    def __new__(cls, clsname, base, clsdict): 
     print "Hello" 
     setattr(cls, 'quantity', graphene.String()) 
     return ObjectTypeMeta.__new__(cls, clsname, base, clsdict) 

class combined_meta(mytype, ObjectTypeMeta): 
    pass 

class Attack(graphene.ObjectType): 
    __metaclass__ = combined_meta 
    def __init__(self, dic): 
     self.quantity = "123" 
     print "Hello world" 
     print dic 

class Query(graphene.ObjectType): 
    attack = graphene.Field(Attack) 
    def resolve_attack(self, args, context, info): 
     return Attack(dict()) 

schema = graphene.Schema(query = Query) 

query = ''' 
{ 
    attack 
} 
''' 

result = schema.execute(query) 
print result.data 

私は多くのエラーで"Hello"を参照してください。..

AssertionError: Attack fields must be a mapping (dict/OrderedDict) with field names as keys or a function which returns such a mapping. 

何か間違っていますか?

答えて

2

__new__を間違った方法で作成しています。メタクラス '__new__の最初のパラメータは、作成しているクラスではなく、メタクラスそのものです。作成されている実際の "cls"は、の戻り値です。この場合、ObjectTypeMeta.__new__によって呼び出されます。 一方、4つ目のパラメータはクラスの名前空間です。これは、新しい属性を挿入する正しい場所です。

ので、ちょうどこのような何かを試してみてください。

import graphene 
from graphene.types.objecttype import ObjectType, ObjectTypeMeta 

class mytype(ObjectTypeMeta): 
    def __new__(metacls, clsname, base, clsdict): 
     print "Hello" 
     clsdict['quantity'] = graphene.String() 
     return ObjectTypeMeta.__new__(metacls, clsname, base, clsdict) 

... 
+0

感謝を!私も1時間前にこの結論に達しました。 – return007