【问题标题】:Error in using Metaclasses in graphene在石墨烯中使用元类时出错
【发布时间】:2017-11-13 22:03:13
【问题描述】:

我正在尝试为我的 graphene.ObjectType 子类创建一个元类。我的主要目标是从一些包含其名称的字符串列表中创建类的属性(即石墨烯对象的字段)。

例如。 list = ['quantity', 'position']

对于这个列表,我的班级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.

我是不是做错了什么...?

【问题讨论】:

    标签: python metaprogramming metaclass graphene-python


    【解决方案1】:

    您创建__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)
    
    ...
    

    【讨论】:

      猜你喜欢
      • 2018-10-22
      • 2020-01-08
      • 2017-05-13
      • 2017-05-11
      • 2022-01-24
      • 2017-03-18
      • 2020-07-27
      • 2020-03-11
      • 2019-12-20
      相关资源
      最近更新 更多