在Python中子类化set时定义__repr__
我正在尝试在Python中对set
对象进行子类化,使用的代码大致如下,但我不知道该如何合理地定义__repr__
。
class Alpha(set):
def __init__(self, name, s=()):
super(Alpha, self).__init__(s)
self.name = name
我想定义__repr__
,这样我就能得到以下输出:
>>> Alpha('Salem', (1,2,3))
Alpha('Salem', set([1, 2, 3]))
但是,如果我不重写__repr__
,我得到的输出就会忽略name
这个值……
>>> Alpha('Salem', (1,2,3))
Alpha([1, 2, 3])
……而如果我重写了__repr__
,我就不能直接访问集合中的值,而是需要创建一个新的集合实例:
class Alpha(set):
…
def __repr__(self):
return "%s(%r, %r)" % (self.__class__.__name__, self.name, set(self))
这样是可以的,但为了__repr__
而创建一个新的集合实例,然后又把它丢掉,感觉有点笨重和低效。
有没有更好的方法来为这种类定义__repr__
?
编辑:我想到的另一个解决方案是:我可以在本地存储这个集合。相比于其他选项(每次调用__repr__
时创建和销毁东西,或者使用某种字符串操作),这似乎稍微整洁一些,但我还是觉得不够理想。
class Alpha(set):
def __init__(self, name, s=()):
super(Alpha, self).__init__(s)
self.name = name
self._set = set(s)
def __repr__(self):
return "%s(%r, %r)" % (self.__class__.__name__, self.name, self._set)
2 个回答
3
我找不到比这个更好的方法了。我想这总比把一组东西扔掉要好。
(Python 2.x)
>>> class Alpha(set):
... def __init__(self, name, s=()):
... super(Alpha, self).__init__(s)
... self.name = name
... def __repr__(self):
... return 'Alpha(%r, set(%r))' % (self.name, list(self))
...
>>> Alpha('test', (1, 2))
Alpha('test', set([1, 2]))
或者,如果你不喜欢写死的类名(虽然其实这没什么大不了的)。
>>> class Alpha(set):
... def __init__(self, name, s=()):
... super(Alpha, self).__init__(s)
... self.name = name
... def __repr__(self):
... return '%s(%r, set(%r))' % (self.__class__.__name__, self.name, list(self))
...
>>> Alpha('test', (1, 2))
Alpha('test', set([1, 2]))
12
我觉得我有一些东西可以满足你的需求,同时还展示了一些基准测试的结果。虽然它们几乎是一样的,但我相信在内存使用上还是有区别的。
#!/usr/bin/env python
import time
class Alpha(set):
def __init__(self, name, s=()):
super(Alpha, self).__init__(s)
self.name = name
def __repr__(self):
return '%s(%r, set(%r))' % (self.__class__.__name__,
self.name,
list(self))
class Alpha2(set):
def __init__(self, name, s=()):
super(Alpha2, self).__init__(s)
self.name = name
def __repr__(self):
return '%s(%r, set(%r))' % (self.__class__.__name__,
self.name,
set(self))
class Alpha3(set):
def __init__(self, name, s=()):
super(Alpha3, self).__init__(s)
self.name = name
def __repr__(self):
rep = super(Alpha3, self).__repr__()
rep = rep.replace(self.__class__.__name__, 'set', 1)
return '%s(%r, %s)' % (self.__class__.__name__,
self.name,
rep)
def timeit(exp, repeat=10000):
results = []
for _ in xrange(repeat):
start = time.time()
exec(exp)
end = time.time()-start
results.append(end*1000)
return sum(results) / len(results)
if __name__ == "__main__":
print "Alpha(): ", timeit("a = Alpha('test', (1,2,3,4,5))")
print "Alpha2(): ", timeit("a = Alpha2('test', (1,2,3,4,5))")
print "Alpha3(): ", timeit("a = Alpha3('test', (1,2,3,4,5))")
结果:
Alpha(): 0.0287627220154
Alpha2(): 0.0286467552185
Alpha3(): 0.0285225152969