给定一个无法修改的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'}