我正在编写一个实现算法的类。该算法具有三个复杂程度。对我来说实现这样的类是有意义的:
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
为level0
,level1
或level2
。
我用其他语言做的方式是:
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
结构成员,我就可以透明地使用该类的其余部分。
答案 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,您也可以将级别传递给类构造函数