我正在编写一个小部件,它可以指定其各个部分的排列方式。

为此,我使用了模块化原理:
“构件块”用于指定任何顺序。

这些“块”被实现为枚举值,其中每个值代表一个单独的组件。

import enum

# The 'blocks'
class E(enum.Enum):
    A = 1
    B = 2
    C = 3

class Test():
    def __init__(self, arrangement):
        # The passed 'arrangement' is translated into the real arrangement.
        real_arrangement = []

        for a in arrangement:
            if a == E.A:
                real_arrangement.append("a_component")
            elif a == E.B:
                real_arrangement.append("b_component")
            elif a == E.C:
                real_arrangement.append("c_component")

        print(real_arrangement)


# The user can specify an arrangement...
arrangement = (E.A, E.C, E.B)

# ... and pass it to the constructor.
Test(arrangement)

# 'real_arrangement' = ("a_component", "c_component", "b_component")


请注意,占位符已替换,但结构相同。



但是,我也想给元素一些属性一些自由。
因此,除了纯枚举值之外,还可以传递可迭代的变量,其中包含枚举值和其他参数。

# the elements are iterables themself.
arrangement = ((10, E.A),
               (20, E.C),
               (5, E.B))

# real_arrangement = ((10, "a_component"), (20, "c_component"), (5, "b_component"))


请注意,结构保持不变。



 因此,我基本上是尝试克隆一个可迭代的并且递归地替换特定值。

我想到的任何方法都很难理解。
也许已经有我可以使用的解决方案了?



上面的代码在Python 3.5.2上运行。

最佳答案

一种选择是检查arrangement is iterable的元素,并根据结果使用适当的列表理解。因此,通过一些重构,您可以执行以下操作:

import enum
import collections

# ...
class Test():
    def __init__(self, arrangement):
        def replace(a):
            if a == E.A:
                return "a_component"
            elif a == E.B:
                return "b_component"
            elif a == E.C:
                return "c_component"
            return a

        real_arrangement = [tuple(replace(e) for e in a) if isinstance(a, collections.Iterable) else replace(a) for a in arrangement]
        print(real_arrangement)

    #...


这将使您在问题中发布的两种类型的arrangement列表(或“混合”列表)都能正常工作。

没有可迭代的元素:

arrangement = (E.A, E.C, E.B)
Test(arrangement)
# ['a_component', 'c_component', 'b_component']


具有所有可迭代的元素:

arrangement = ((10, E.A), (20, E.C), (5, E.B), (1, E.A))
Test(arrangement)
# [(10, 'a_component'), (20, 'c_component'), (5, 'b_component'), (1, 'a_component')]


具有一些可迭代的元素:

arrangement = (E.A, (20, E.C), (5, E.B), (1, E.A))
Test(arrangement)
# ['a_component', (20, 'c_component'), (5, 'b_component'), (1, 'a_component')]

07-24 09:28