在 Python 中子类化时定义 __repr__

发布于 2024-12-21 01:26:21 字数 1232 浏览 2 评论 0原文

我正在尝试使用类似于下面的代码在 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__ ,我得到的输出将忽略 < code>name value…

>>> 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)

I'm trying to subclass the set object in Python, using code similar to the below, but I can't work out a sensible definition of __repr__ to use.

class Alpha(set):
    def __init__(self, name, s=()):
        super(Alpha, self).__init__(s)
        self.name = name

I'd like to define __repr__ in such a way that I can get the following output:

>>> Alpha('Salem', (1,2,3))
Alpha('Salem', set([1, 2, 3]))

However, if I don't override __repr__, the output I get ignores the name value…

>>> Alpha('Salem', (1,2,3))
Alpha([1, 2, 3])

…while if I do override __repr__, I can't get direct access to the values in the set without creating a new set instance:

class Alpha(set):
    …
    def __repr__(self):
        return "%s(%r, %r)" % (self.__class__.__name__, self.name, set(self))

This works, but creating a new set instance for __repr__ that will then be disposed of seems clunky and inefficient to me.

Is there a better way to define __repr__ for this sort of class?

Edit: Another solution that has occurred to me: I can store the set locally. It seems slightly neater than the other options (creating and destroying something for every call of __repr__ or using some form of string manipulation), but still seems less than ideal to me.

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情痴 2024-12-28 01:26:21

我想除了展示一些基准之外,我还有一些东西可以让你得到你想要的东西。尽管我确信内存使用情况存在差异,但它们几乎都是相同的。

#!/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

I think I have something that gets you what you want, in addition to showing some benchmarks. They are almost all equivalent though I am sure there is a difference in memory usage.

#!/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))")

Results:

Alpha(): 0.0287627220154

Alpha2(): 0.0286467552185

Alpha3(): 0.0285225152969

风流物 2024-12-28 01:26:21

我找不到比这样做更好的方法。我想这比扔掉一套要好。

(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]))

I couldn't find any better way than to do this. I suppose it's better than throwing away a set though.

(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]))

Or, if you don't like the hardcoded class name (though it really shouldn't matter).

>>> 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]))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文