在Python中对类进行别名处理
我正在写一个类来实现一个算法。这个算法有三个复杂度等级。对我来说,按照这样的方式来实现这些类是有道理的:
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
有没有一种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
)可以从命令行获取。