2017-06-12 79 views
0

我想爲我的graphene.ObjectType子類創建一個meta類。我的主要目標是從包含其名稱的字符串列表中創建類的屬性(即Graphene對象的字段)。在石墨烯中使用Metacles的錯誤

例如,​​

對於這份名單,我的課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」是type.__new__的返回 - 在這種情況下,由ObjectTypeMeta.__new__調用。 另一方面,你得到的第四個參數是類名字空間 - 它是注入你的新屬性的正確位置。

所以,只是嘗試這樣的事:

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

謝謝!我也只在一小時前得出這個結論。 – return007