在Python中对类进行别名处理

1 投票
4 回答
1413 浏览
提问于 2025-04-15 14:02

我正在写一个类来实现一个算法。这个算法有三个复杂度等级。对我来说,按照这样的方式来实现这些类是有道理的:

class level0:
    def calc_algorithm(self):
        # level 0 algorithm
        pass

    # more level0 stuff

class level1(level0):
    def calc_algorithm(self):
        # level 1 algorithm
        pass

    # more level1 stuff

class level2(level1):
    def calc_algorithm(self):
        # level 2 algorithm
        pass

    # more level2 stuff

我希望在每个类中都能重写 calc_algorithm 这个方法。根据某个命令行选项,我想在数据上运行等级0、等级1或等级2的算法。这是我调用算法的方式:

for offset in itertools.product(*map(xrange, (dim[0] - 1, dim[1] - 1, dim[2] - 1))):
    algorithm(offset).calc_algorithm    

这里的 algorithm 可以是 level0level1level2

如果是在其他编程语言中,我会这样做:

for offset in itertools.product(*map(xrange, (dim[0] - 1, dim[1] - 1, dim[2] - 1))):
    if (level == 0):        
        level0(offset).calc_algorithm    
    else:
        if (level == 1):        
            level1(offset).calc_algorithm    
        else:
            level2(offset).calc_algorithm    

有没有一种Python的方式,可以让一个类别名指向另一个类,这样我就可以这样做:

algorithm = (level == 0) and level0 or (level == 1) and level1 or level2

然后像上面那样调用 algorithm


为了比较,在Specman这个面向方面的语言中,我可以这样写这个类:

struct algorithm {
    level: uint;
    // common stuff for all levels

    calc_algorithm() is empty;

    when (level == 0) {
        calc_algorithm() is only {
            // level 0 algorithm
        };
    };
    when (level == 1) {
        calc_algorithm() is only {
            // level 1 algorithm
        };
    };
    when (level == 1) {
        calc_algorithm() is only {
            // level 1 algorithm
        };
    };

};

然后一旦我设置了 level 这个结构体成员,我就可以透明地使用这个类的其余部分。

4 个回答

3

关键在于——与其他一些语言不同,在那些语言中类是“特殊的”,你需要用一些不寻常的方法来“别名”它们——在Python中,类本身就是一等公民,可以用普通的变量来引用。

所以,你可以简单地通过说“b=a”来把‘a’别名为‘b’。

有没有一种Python风格的方法可以把一个类别名为另一个类,这样我就可以这样写:

algorithm = (level == 0) and level0 or (level == 1) and level1 or level2

当然可以,这样写是完全正确的,已经可以正常工作了!

...不过现代Python有了if/else表达式,所以现在一般会这样写:

algorithm= level0 if level==0 else level1 if level==1 else level2

但如果用序列访问,可能会比用两个条件更简单:

algorithm= (level0, level1, level2)[level]
4
dispatch = {0:level0, 1:level1, 2:level2}
algo = dispatch[offset]()   # "calling" a class constructs an instance.
algo.calc_algorithm()
class_name = "level%d" % offset
klass = globals()[class_name]
algo = klass()
algo.calc_algorithm()

如果你更喜欢自省:

11

你是在找类似这样的东西吗?

dispatch = {0: level0, 1: level1, 2:level2}
dispatch[offset].calc_algorithm

显然,键(还有 offset)可以从命令行获取。

撰写回答