python - 在Python中配置类的最优雅的方式是什么?

标签 python

我正在模拟一个分布式系统,其中所有节点都遵循某种协议(protocol)。这包括评估协议(protocol)中的一些小变化。变体意味着单一方法的替代实现。 所有节点始终遵循相同的变化,这是由实验配置决定的(在任何给定时间只有一个配置处于事件状态)。在不牺牲性能的情况下,最清晰的方法是什么?

由于实验可能非常广泛,因此我显然不需要任何条件。在我刚刚使用继承之前,例如:

class Node(object):

    def dumb_method(self, argument):
        # ...    

    def slow_method(self, argument):
        # ...

    # A lot more methods

class SmarterNode(Node):

    def dumb_method(self, argument):
        # A somewhat smarter variant ...

class FasterNode(SmarterNode):

    def slow_method(self, argument):
        # A faster variant ...

但现在我需要测试所有可能的变体并且不希望指数数量的类使源变得困惑。我也希望其他偷看代码的人能够以最小的努力理解它。您有什么建议?

编辑:有一件事我没有足够强调:对于所有设想的用例,似乎在配置时修补类是好的。我的意思是:它可以通过简单的 Node.dumb_method = smart_method 来工作。但不知何故,感觉不太对劲。这种解决方案会让随机的聪明读者感到头疼吗?

最佳答案

您可以使用type函数创建新的子类型。您只需将子类 namespace 作为字典提供给它即可。

# these are supposed to overwrite methods
def foo(self):
    return "foo"

def bar(self):
    return "bar"


def variants(base, methods):
    """
        given a base class and list of dicts like [{ foo = <function foo> }] 
         returns types T(base) where foo was overwritten
    """
    for d in methods:
        yield type('NodeVariant', (base,), d)


from itertools import combinations
def subdicts(**fulldict):
    """ returns all dicts that are subsets of `fulldict` """
    items = fulldict.items()
    for i in range(len(items)+1):
        for subset in combinations(items, i):
            yield dict(subset)

# a list of method variants
combos = subdicts(slow_method=foo, dumb_method=bar)

# base class
class Node(object):
        def dumb_method(self):
            return "dumb"
        def slow_method(self):
            return "slow"

# use the base and our variants to make a number of types
types = variants(Node, combos)

# instantiate each type and call boths methods on it for demonstration
print [(var.dumb_method(), var.slow_method()) for var
          in (cls() for cls in types)]

# [('dumb', 'slow'), ('dumb', 'foo'), ('bar', 'slow'), ('bar', 'foo')]

关于python - 在Python中配置类的最优雅的方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6680029/

相关文章:

python - 使用 glob 获取没有文件扩展名的文件名

Python多处理: TypeError: 'Queue' object is not iterable

python - 忽略与正则表达式不完全匹配的字符串?

Python,减去格式中的两个不同时间(HH :MM:SS - HH:MM:SS)

python - 创建索引时传递映射的正确格式是什么?

具有大型数组的 Windows 上的 Python 多处理

python - 如何将轴标签移动到 matplotlib 中的箭头附近

python - Django URL 正则表达式接受任何数字或直到 99 的任何数字

python - 如何使用特定的 python 版本创建 conda 环境?

python - 我想将标签 numpy 数组转换为二进制矩阵?