如何整理参数功能以从枚举创建一组值



给定一个无法修改的Enum对象,以及一个自定义Query类,该类应在给定不同参数的情况下生成Enum值的编译:

from enum import Enum
class Fields(Enum):
a = ["hello", "world"]
b = ["foo", "bar", "sheep"]
c = ["what", "the"]
d = ["vrai", "ment", "cest", "vrai"]
e = ["foofoo"]
class Query:
def __init__(self, a=True, b=True, c=False, d=False, e=False):
self.query_fields = set()
self.query_fields.update(Fields.a.value) if a else None
self.query_fields.update(Fields.b.value) if b else None
self.query_fields.update(Fields.c.value) if c else None
self.query_fields.update(Fields.d.value) if d else None
self.query_fields.update(Fields.e.value) if e else None

可以获得自定义的query_fields集,例如:

[out]:

>>> x = Query()
>>> x.query_fields
{'bar', 'foo', 'hello', 'sheep', 'world'}
>>> x = Query(e=True)
>>> x.query_fields
{'bar', 'foo', 'foofoo', 'hello', 'sheep', 'world'}

问题:Query初始化函数中,我们必须迭代每个类参数,并执行类似self.query_fields.update(Fields.a.value) if a else None的操作,是否有其他方法可以在不硬编码每个参数的情况下实现Query().query_fields的相同行为和输出

有关更通用的解决方案,请参阅以下内容;对于Fields的具体解决方案,并且不需要*args(或*members,视情况而定…),请查看Tomer Shetah的答案。


通用解决方案

为了使Query更通用并可与其他枚举一起使用,我将指定您想要的Field成员:

class Query:
#
def __init__(self, *members):
self.query_fields = set()
for member in members:
self.query_fields.update(member.value)

使用中:

>>> x = Query()
>>> x.query_fields
set()

>>> y = Query(Fields.a, Fields.c)
>>> y.query_fields
{'world', 'the', 'hello', 'what'}

如果你的默认值很常见,你可以把它们放在另一个变量中并使用:

>>> fields_default = Fields.a, Fields.b
>>> z = Query(*fields_default)
>>> z.query_fields
{'foo', 'bar', 'world', 'hello', 'sheep'}

您可以迭代Fields以获取所有元素,然后使用.name或.value来获取相应的属性。

from enum import Enum

class Fields(Enum):
a = ["hello", "world"]
b = ["foo", "bar", "sheep"]
c = ["what", "the"]
d = ["vrai", "ment", "cest", "vrai"]
e = ["foofoo"]

class Query:
defaults = [True, True, False, False, False]
def __init__(self, **kwargs):
self.query_fields = set()
for attr, default in zip(Fields, self.defaults):
if attr.name in kwargs:
if kwargs[attr.name]:
self.query_fields.update(attr.value)
elif default:
self.query_fields.update(attr.value)

x = Query()
print(x.query_fields)
x = Query(a=False, e=True)
print(x.query_fields)

请注意,字段中的元素数量及其顺序是Query.defaults中的硬编码,但我认为不这样做是没有意义的。

阅读后,是否获取传递给函数的参数的列表/元组/dict?我发现不用*args就可以实现。

有一个简短的版本:

class Query:
def __init__(self, a=True, b=True, c=False, d=False, e=False):
self.query_fields = set()
local_variables = locals()
[self.query_fields.update(Fields[local].value) for local in local_variables if local_variables[local] is True]

或者更详细的选项:

class Query:
def __init__(self, a=True, b=True, c=False, d=False, e=False):
self.query_fields = set()
local_variables = locals()
for local in local_variables:
if local_variables[local] is True:
self.query_fields.update(Fields[local].value)

两种实现中的输出:

x = Query()
print(x.query_fields)

是:

{'hello', 'foo', 'bar', 'sheep', 'world'}

和:

x = Query(e = True)
print(x.query_fields)

是:

{'foo', 'hello', 'sheep', 'foofoo', 'bar', 'world'}

最新更新