【问题标题】:using __class__ to change python class, Heap Error使用 __class__ 更改 python 类,堆错误
【发布时间】:2013-09-26 01:18:23
【问题描述】:

我正在尝试使从列表扩展的 class= 返回其自身的切片而不是列表类型。我想这样做的原因是因为我有许多其他方法来操作 A 的实例。
我正在运行 python 2.7.3 说我有:

class B():
def __init__(self, t, p):
    self.t = t
    self.p = p

class Alist(list):
    def __init__(self, a_list_of_times = []):
        for a_time in a_list_of_times:
            self.append(a_time )
    def __getslice__(self, i, j):
        return super(Alist, self).__getslice__(i,j)

    def plot_me(self):
        pass
        # other code goes here!


alist1 = Alist()
for i in range(0, 1000000):
    alist1.append(B(i, i))                  # yes ten million, very large list!
alist = alist1[1000:200000]                 # will return a list!
alist2 = Alist(alist)                # will return Alist istance 

问题在于,在制作变量 b 时重新制作整个列表非常慢(与切片相比)。我想要做的只是将 alist 的类(当前为 list 类型)更改为 Alist

当我尝试时:

alist.__class__ = Alist
>>>> TypeError: __class__ assignment: only for heap types.

这很可悲,因为我可以为自己的对象类型做到这一点。 我知道这不是标准的,但它已经完成了。 Reclassing an instance in Python.

有没有办法解决这个问题?此外,我显然简化了问题,我的对象更复杂一些。我主要发现将列表重新制作成我的 Alist 版本很慢。而且我需要经常做这个操作(不可避免)。有没有办法重制A?或解决此问题以使其加快速度?

在我的版本中,我可以在 0.07 秒内完成大约 10,000(我的切片大小)切片,而将其转换为我的 Alist 版本需要 3 秒。

【问题讨论】:

  • 我认为阅读一些面向对象编程的知识会对您有所帮助。 Python 使用 C 在内部执行列表操作(如切片),但通过在纯 Python 中手动附加一百万个元素来构建 Alist 总是非常慢。相反,您应该尽可能使用本机列表方法,并将结果包装在 Alist 构造函数中,然后直接从该方法返回 Alist。你离需要像分配给 __class__ 这样的 hacky 东西还有很长的路要走。

标签: python


【解决方案1】:

UserList 类(在 Python 3 中移至 collections)就是为此完美设计的。它是一个list,但有一个data 属性,您可以在不复制的情况下存储底层list

from UserList import UserList

class Alist(UserList):
    def __init__(self, iterable, copy=True):
        if copy:
            super(Alist, self).__init__(iterable)

        else:
            self.data = iterable

    def plot_me(self):
        pass

【讨论】:

  • 这太棒了!我只是按照你说的做了,将类 Alist(list) 更改为 Alist(userlist),一切正常。快速的问题。如果我添加一个快速检查以确保“可迭代”中的所有内容都是正确的对象类型,它会减慢很多吗?就像 if type(x) == datetime for x in iterable (不是pythonic,只是我知道只是想看看是否可行!)
猜你喜欢
  • 1970-01-01
  • 2018-09-18
  • 1970-01-01
  • 2012-03-25
  • 1970-01-01
  • 1970-01-01
  • 2017-09-19
  • 1970-01-01
  • 2012-12-13
相关资源
最近更新 更多