OOP继承eval(repr())非理想输出

2024-04-26 19:04:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了一个从类列表继承的类:

class Queue2(list):
    'a queue class, subclass of list'

    def isEmpty(self):
        'returns True if queue is empty, False otherwise'
        return (len(self)==0)

    def dequeue(self):
        'remove and return item at front of queue'
        return self.pop(0)

    def enqueue(self, item):
        'insert item at rear of queue'
        return self.append(item)

尝试运行eval(repr())时,发生AttributeError:

>>> queue2 = Queue2(['a','b','c'])
>>> duplicate = eval(repr(queue2))
>>> duplicate
['a', 'b', 'c']
>>> duplicate.enqueue('d')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'enqueue'

我意识到repr(queue2)将queue2对象更改为str,eval()方法使其成为列表。你知道吗

有办法解决这个问题吗?你知道吗

编辑1: 以下是我的尝试: 1我试图重写repr函数:

def __repr__(self):
    return self

def __eval__(self):
    return self

结果:

>>> queue2 = Queue2(['a','b','c'])
>>> duplicate = eval(repr(queue2))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __repr__ returned non-string (type Queue2)

2。我试图在继承中包含str:

class Queue2(list,str):
    'a queue class, subclass of list'

    def isEmpty(self):
        'returns True if queue is empty, False otherwise'
        return (len(self)==0)

    def dequeue(self):
        'remove and return item at front of queue'
        return self.pop(0)

    def enqueue(self, item):
        'insert item at rear of queue'
        return self.append(item)

    def __eval__(self):
        return Queue2(self)

结果:

Traceback (most recent call last):
File "ch8.py", line 168, in <module>
class Queue2(list,str):
TypeError: Error when calling the metaclass bases
multiple bases have instance lay-out conflict

Tags: ofselfreturnqueuedefevalitemat
2条回答

您需要编写自己的__repr__,它返回一个字符串,当您eval创建类时,该字符串将构建类的新实例。没有__eval__特殊的方法,所以尝试用它来做事情是没有任何效果的。你知道吗

下面是一个合理的__repr__实现,应该适合您:

def __repr__(self):
    return "{}({})".format(type(self).__name__, super().__repr__())

这将生成一个如下所示的字符串:"Queue2(['a', 'b', 'c'])"。当它被eval编辑时,它将生成一个Queue2的新实例,而不是一个您想要的列表。你知道吗

注意,虽然有一个__repr__可以传递给eval是很好的,但这不是一个要求。有时,您会有一个类,它的设计不允许您在一个步骤中重新创建它(例如,也许您的构造函数只创建空队列,而不是那些已经包含内容的队列)。在这种情况下,一种约定是在类中包含信息的文本周围使用尖括号(例如"<Queue2 contents: ['a', 'b', 'c']>")。许多标准Python对象都有这样的repr(比如函数对象)。你知道吗

简单的方法是定义__repr__,它返回用列表初始化的类Queue2

class Queue2(list):
    'a queue class, subclass of list'

    def isEmpty(self):
        'returns True if queue is empty, False otherwise'
        return (len(self)==0)

    def dequeue(self):
        'remove and return item at front of queue'
        return self.pop(0)

    def enqueue(self, item):
        'insert item at rear of queue'
        return self.append(item)

    def __repr__(self):
        return "Queue2({})".format(super().__repr__())


queue2 = Queue2(['a','b','c'])
duplicate = eval(repr(queue2))
print(duplicate)
duplicate.enqueue('d')
print(duplicate)

# Queue2(['a', 'b', 'c'])
# Queue2(['a', 'b', 'c', 'd'])

相关问题 更多 >