Когда я ввожу переменную, которая хранит объект, он продолжает возвращать экземпляр этого объекта, а не список, который я хочу - PullRequest
0 голосов
/ 14 ноября 2018
class Stack(object):

    def __init__(self):
        self.stack = []

    def __str__(self):
        return self.stack

    def push(self, item):
        self.stack.append(item)

    def pop(self):
        popped = self.stack.pop()
        print(popped)

    def isEmpty(self):
        if len(self.stack) == 0:
            print("True")
        else:
            print("False")

    def __len__(self):
        return len(self.stack)

Я пытаюсь вернуть список при вызове объекта в интерактивном режиме. Это то, что продолжает происходить:

>>> s = Stack()
>>> s.push("Plate 1")
>>> s.push("Plate 2")
>>> s.push("Plate 3")
>>> s
<__main__.Stack object at 0x0000017E06ED4E10>

Ответы [ 5 ]

0 голосов
/ 14 ноября 2018

Я думаю, что методология, которую вы можете искать, документирована здесь: https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables

Модифицированный пример кода:

class Stack:
    stack_list = []
    def __init__(self, name):
        self.name = name
    def push(self, item):
        self.stack_list.append(item)

Метод «push» добавляет элементы в «stack_list»когда это называется.

stack = Stack('the_stack')
stack.push('example1')
stack.push('example2')
stack.push('example3')
stack.stack_list
['example1', 'example2', 'example3']
0 голосов
/ 14 ноября 2018

Вместо возврата 'self.stack' из функции __str__(), вы можете вернуть список, как показано ниже:

class Stack(object):

def __init__(self):
    self.stack = []

def __str__(self):
    return str(list(plates for plates in self.stack))

def push(self, item):
    self.stack.append(item)

def pop(self):
    popped = self.stack.pop()
    print(popped)

def isEmpty(self):
    if len(self.stack) == 0:
        print("True")
    else:
        print("False")

def __len__(self):
    return len(self.stack)

s = Stack()
s.push("Plate 1")
s.push("Plate 2")
s.push("Plate 3")
print(s)

Вывод:

['Plate 1', 'Plate 2', 'Plate 3']
0 голосов
/ 14 ноября 2018

Я бы предложил сначала переопределить __repr__ вместо __str__, чтобы соответствовать вашей цели, однако ниже вы можете найти оба подхода для класса:

class Stack(object):
    def __init__(self):
        self.stack = []
    def __str__(self):
        return str(self.stack)
    def __repr__(self):
        return repr(self.stack)
    def push(self, item):
        self.stack.append(item)
    def pop(self):
        popped = self.stack.pop()
        print(popped)
    def isEmpty(self):
        if len(self.stack) == 0:
            print("True")
        else:
            print("False")
    def __len__(self):
        return len(self.stack)

По сути, то, что произошло раньше, вы вызывали представление объекта, который вы назвали, когда просто указали s.

Чтобы преобразовать его, скажем, в строковое представление, которое вы могли бы сделать:

def __str__(self):
    return str(self.stack)

Аналогично, вы можете сделать это за __repr__.

Пример его исполнения:

>>> s = Stack()
>>> print(s)
[]
>>> s.push(1)
>>> print(s) #this uses __str__
[1]
>>> s  #this uses __repr__
[1]

Для более подробной информации о различиях между ними вы можете проверить следующую ветку Разница между __str__ и __repr __?

0 голосов
/ 14 ноября 2018

Здесь следует отметить две вещи:

  1. Когда REPL обнаруживает объект, он использует свой метод __repr__ для представления.
  2. Ваш метод __str__ вызоветошибки, потому что он не возвращает строку.

После запуска вашего кода можно наблюдать следующее поведение:

>>> s.stack
>>> ['Plate 1', 'Plate 2', 'Plate 3']
>>> print(s)
[...]
TypeError: __str__ returned non-string (type list)
>>> repr(s)
>>> '<__main__.Stack object at 0x7fe358f7e240>'

Чтобы исправить эти проблемы, внедрите __repr__, дляПример, подобный следующему:

def __repr__(self):
    return repr(self.stack)

Теперь

>>> s
>>> ['Plate 1', 'Plate 2', 'Plate 3']

показывает содержимое s.stack.Кроме того, вы можете удалить метод __str__, так как при печати __repr__ будет вызываться как запасной вариант, когда нет реализации __str__.

>>> del Stack.__str__
>>> print(s)
['Plate 1', 'Plate 2', 'Plate 3']

Если вы хотите сохранить __str__, убедитесь, что изменили его для возврата объекта str, в противном случае вы получите TypeError, как показано выше.


Немного больше о __repr__:

В идеале метод должен возвращать строку, чтобы при вставке копии в интерпретатор создавался равный объект.Поскольку ваш метод __init__ не принимает аргументов, здесь невозможно отобразить информативную строку, которая будет оценена как экземпляр Stack, и одновременно показать содержимое стека.

Если вы изменили __init__ на

def __init__(self, iterable=None):
    if iterable is None:
        self.stack = []
    else:
        self.stack = list(iterable)

, вы можете изменить __repr__ на

def __repr__(self):
    return 'Stack({!r})'.format(self.stack)

, который будет выглядеть следующим образом при реализации:

>>> s
>>> Stack(['Plate 1', 'Plate 2', 'Plate 3'])

... eval'ing этой строки создаст Stack с тем же содержимым.


Пока мы в этом, рассмотрим реализацию __eq__ для хорошей меры ...

def __eq__(self, other):
    return isinstance(other, Stack) and self.stack == other.stack

... такой, что:

>>> s == eval(repr(s))
>>> True
0 голосов
/ 14 ноября 2018

Интерактивная оболочка Python печатает представление, а не строку, поэтому вам необходимо реализовать метод __repr__.Но и __str__, и __repr__ всегда должны возвращать строку.Так что попробуйте:

def __str__(self):
    return str(self.stack)

def __repr__(self):
    return repr(self.stack)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...