python中专门命名的动态类方法

2024-04-19 16:01:02 发布

您现在位置:Python中文网/ 问答频道 /正文

在下面的示例中,我必须显式定义ReturnValue类中的所有'resolve'方法。你知道吗

如果我能在一个循环中自动定义这些方法会更简洁,因为它们几乎都做相同的事情,唯一的区别是方法的名称与返回的类成员变量的名称匹配。你知道吗

这在Python2.7中是可能的吗?你知道吗

import graphene


class ApiObj(object):
    @staticmethod
    def get_values_as_dictionary():
        return {'dog': 'pound', 'cat': 'nip', 'horse': 'fly', 'bear': 'down'}


class ReturnKeys(graphene.Interface):
    dog = graphene.String()
    cat = graphene.String()
    horse = graphene.String()
    bear = graphene.String()


class ReturnValue(graphene.ObjectType):
    class Meta:
        interfaces = (ReturnKeys,)

    def resolve_dog(self):
        return self.dog

    def resolve_cat(self):
        return self.cat

    def resolve_horse(self):
        return self.horse

    def resolve_bear(self):
        return self.bear


api = ApiObj()
value_dict = api.get_values_as_dictionary()
rv = ReturnValue(**value_dict)

print rv.resolve_cat()
print rv.resolve_dog()
print rv.resolve_horse()
print rv.resolve_bear()

Tags: 方法selfstringreturndefclassgraphenecat
2条回答

我认为这应该管用:

class ReturnValue(graphene.ObjectType):
    class Meta:
        interfaces = (ReturnKeys,)


def set_resolve_method(animal):
    setattr(
        ReturnValue,
        'resolve_' + animal,
        lambda self: getattr(self, animal)
    )

for animal in ('dog', 'cat', 'horse', 'bear'):
    # this function scoped the variable `animal`
    set_resolve_method(animal)

但是你看,它没有节省太多的台词。我认为明确定义每个方法实际上是一种更好的方法。如果您试图重用一些复杂的代码,只需将公共部分从每个方法中分离出来,并将它们放入一个单独的函数中,如下所示:

def common_function(animal):
    pass  # do something here


class ReturnValue(graphene.ObjectType):
    class Meta:
        interfaces = (ReturnKeys,)

    def resolve_dog(self):
        return common_function(self.dog)

    def resolve_cat(self):
        return common_function(self.cat)

    ...

另一种方法是使用内置的__getattribute__截获方法调用,并在收到“resolve”方法时返回特定属性。你知道吗

此代码应执行以下操作:

class ReturnValue(graphene.ObjectType):
    class Meta:
        interfaces = (ReturnKeys,)

    def __getattribute__(self, attr):
        if attr.startswith("resolve_"):
            return lambda: getattr(self, attr[8:])
        return super().__getattribute__(attr)

与@Philip Tzou answer不同的是,这里我们并不像setattr那样添加类中的每个方法。相反,我们直接返回需求中的属性。根据你的使用情况,这可能是好的或不好的。你知道吗

另外,Philip在回答结束时提到的内容也很重要,如果替换这一行,可以在上面的代码中实现:

return lambda: getattr(self, attr[8:])

为此:

return lambda: self.common_function(attr[8:])

这段代码是用python3编写的,因此您可能需要更改super()语法才能在python2中工作。你知道吗

相关问题 更多 >