首页 > 解决方案 > 迭代和调用实例方法是正确的“pythonic”方式吗?

问题描述

我想定义要在类变量中调用的方法列表。我想迭代实例方法并在它们位于配置类变量中时调用它们。下面的例子是正确的和 pythonic 的方式来做到这一点,还是你会建议别的?

编辑: 它的目的:我的真实类(让我们调用它record)将我的数据类定义为初始化位置参数,其中包含嵌套的数据类(这是 json API 响应的对象表示)。Record类定义了多个 getter 和几个转换器。最后,一种方法(例如def consruct_useless_dict(self)构造一条将插入到 SQL 表中的记录。所以基本上config包含 SQL 表中需要的字段,并且每个字段都有自己的 getter 方法(如果需要,还有转换器)

class Foo:
    config = ['a','b','c','d']

    def __init__(self, string: str):
        self.string = string

    def a(self):
        return 'a' if 'a' in self.string else 'XXX'

    def b(self):
        return 'b' if 'b' in self.string else 'XXX'

    def c(self):
        return 'c' if 'c' in self.string else 'XXX'

    def d(self):
        return 'd' if 'd' in self.string else 'XXX'

    def construct_useless_dict(self):
        methods = [i for i in dir(self) if i in self.config]
        data = {k: getattr(self, method)() for k in self.config for method in methods if method == k}
        return data


inst = Foo('abc')
x = inst.construct_useless_dict()
print(x)
>>> {'a': 'a', 'b': 'b', 'c': 'c', 'd': 'XXX'}

标签: pythonloopsclassclass-method

解决方案


这是另一种方法。config您可以使用如下元类自动为对象中的每个字段创建属性:

def config_setup(what, bases=None, dict=None):
    """Metaclass which takes the same arguments as `type()`"""
    cls = type(what, bases, dict)

    def getter_for_field(f):
        return lambda self: f if f in self.string else 'XXX'

    for f in dict['config']:
        setattr(cls, f, property(getter_for_field(f)))

    return cls


class Foo(metaclass=config_setup):
    config = ['a', 'b', 'c', 'd']

    def __init__(self, string: str):
        self.string = string

    def construct_useless_dict(self):
        data = {k: getattr(self, k) for k in self.config}
        return data


foo = Foo('abc')
assert foo.d == 'XXX'

print(foo.construct_useless_dict())
print(Foo('abdc').construct_useless_dict())

推荐阅读