【问题标题】:How to collate the arguments features to create a set of values from an Enum?如何整理参数功能以从枚举中创建一组值?
【发布时间】:2021-05-09 00:19:51
【问题描述】:

给定一个无法修改的 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,例如:

[出]:

>>> 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 没有对每个参数进行硬编码

【问题讨论】:

  • 看看是否有其他方法可以在不使用 *args 的情况下获得效果。否则,赏金将归于 Ethan
  • Query.__init__ 中的每个成员姓名是否都在场?换句话说,Query 只能与 Fields 一起使用?
  • Query 的 init 不仅应该适用于 Fields 类型,还应该能够采用其他类型。例如。也许有一个 str 类型的 f 变量。
  • 我不明白你最后的评论——你能在你的问题中添加一个例子吗?

标签: python class object enums set


【解决方案1】:

有关更通用的解决方案,请参见下文;对于Fields 的解决方案,并且不需要*args(或*members,视情况而定......)请查看Tomer Shetah's answer


一般解决方案

为了使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'}

【讨论】:

    【解决方案2】:

    您可以遍历 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 中是硬编码的,但我认为不这样是没有意义的。

    【讨论】:

      【解决方案3】:

      看了Get a list/tuple/dict of the arguments passed to a function?之后发现不用*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'}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-10
        • 2020-04-21
        • 1970-01-01
        • 2015-07-07
        • 1970-01-01
        • 2016-12-10
        • 2021-01-17
        相关资源
        最近更新 更多