在石墨烯中使用元类的错误
Error in using Metaclasses in graphene
我正在尝试为我的 graphene.ObjectType 子 class 创建一个元数据 class。我的主要 objective 是从一些包含其名称的字符串列表中创建 class 的属性(即石墨烯对象的字段)。
例如。 list = ['quantity', 'position']
对于这个列表,我的 class 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.
我做错了什么吗...?
您正在以错误的方式创建 __new__
。 metaclass' __new__
的第一个参数是 metaclass 本身,而不是您正在创建的 class。正在创建的实际 "cls" 是 type.__new__
的 return - 在本例中由 ObjectTypeMeta.__new__
调用。
另一方面,您获得的第四个参数是 class 命名空间 - 它是注入新属性的正确位置。
所以,试试这样的方法:
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)
...
我正在尝试为我的 graphene.ObjectType 子 class 创建一个元数据 class。我的主要 objective 是从一些包含其名称的字符串列表中创建 class 的属性(即石墨烯对象的字段)。
例如。 list = ['quantity', 'position']
对于这个列表,我的 class 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.
我做错了什么吗...?
您正在以错误的方式创建 __new__
。 metaclass' __new__
的第一个参数是 metaclass 本身,而不是您正在创建的 class。正在创建的实际 "cls" 是 type.__new__
的 return - 在本例中由 ObjectTypeMeta.__new__
调用。
另一方面,您获得的第四个参数是 class 命名空间 - 它是注入新属性的正确位置。
所以,试试这样的方法:
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)
...