在Python中别名一个类

时间:2009-09-02 18:59:53

标签: python class

我正在编写一个实现算法的类。该算法具有三个复杂程度。对我来说实现这样的类是有意义的:

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    

其中algorithmlevel0level1level2

我用其他语言做的方式是:

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    

是否有一种Pythonic方法来对一个类进行别名以引用另一个类,以便我可以这样做:

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 个答案:

答案 0 :(得分:11)

你在寻找这些方面的东西吗?

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

键(和offset)显然可以来自命令行。

答案 1 :(得分: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()

答案 2 :(得分:3)

关键在于 - 与其他一些类别'特殊'的语言不同,你必须有一些不寻常的'别名'方法 - 在Python中,类本身就是一流的对象,完美引用正常变量。

所以'a'可以别名为'b',就像说'b = a'。

  

是否有一种Pythonic方法来对一个类进行别名以引用另一个类,以便我可以这样做:

     

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]

答案 3 :(得分:2)

就个人而言,我不会创建3个类,而是使用3种不同的计算方法创建一个类,并根据需要改变官方计算方法(计算界面)。 例如:

class algorithm:
    def __init__(self, level = 0):

        self.level = level
        self.calcFunctions = {0: self.calcLevel0, 1: self.calcLevel1, 2:self.calcLevel2}
        #initial value for calc function
        self.setLevel(level)

    def setLevel(self, newlevel):
        self.level = newlevel
        self.calc = self.calcFunctions[level]       

    def calcLevel0(self):
        """Level 0 calc algorithm"""
        #...
        pass

    def calcLevel1(self):
        """Level 1 calc algorithm"""
        #...
        pass

    def calcLevel2(self):
        """Level 2 calc algorithm"""
        #...
        pass


#class in use:

#level (taken from command line in your case)
level = 1

alg = algorithm()
alg.setLevel(level)
alg.calc()

如果您不需要在执行期间以非语义方式更改calcFunction,您也可以将级别传递给类构造函数