Как распечатать фактические данные, а не места в памяти объекта? - PullRequest
0 голосов
/ 04 ноября 2019

Я пытаюсь сделать связанный список в Python и хотел бы распечатать вещи, но его печать в качестве места в памяти. Мы узнали, как исправить это в классе, но сейчас я на полугодии, и нам не с кем спросить.

Пример того, что я сейчас получаю:

List: <__main__.LinkedList object at 0x02EA0100>
 index: 0    data: 1     item: <__main__.Node object at 0x02EA00D0>  pointer: <__main__.Node object at 0x02EA0148>
 index: 1    data: 6     item: <__main__.Node object at 0x02EA0148>  pointer: <__main__.Node object at 0x02EA0190>
 index: 2    data: 3     item: <__main__.Node object at 0x02EA0190>  pointer: None

Это не очень полезномне.

Метод, который я использую, чтобы получить этот шедевр:

def PrintList(self):
    item = self.list_start
    index = 0
    print(f"List: {self}")
    while item:
        print(
            f"\t index: {index}\t data: {item.data}\t item: {item}\t pointer: {item._get_pointer()}"
            )
        item = item._get_pointer()
        index += 1

Я уверен, что в строке печати что-то не так, я просто не могу это определить.

Я знаю, что вы не должныздесь можно загрузить множество кода, но мне нужно указать контекст

Класс узла:

class Node:
def __init__(self, data=None, pointer=None):
    self.data = data
    self.poiner = pointer

def PrintNode(self):
    print(f"Node Data: {self.data}\t self: {self}\t pointer: {self.pointer}\n")

def _set_pointer(self, pointer):
    self.pointer = pointer

def _get_pointer(self):
    return self.pointer

Класс LinkedLis:

class LinkedList:
def __init__(self):
    self.list_start = None

def PrintList(self):
    item = self.list_start
    index = 0
    print(f"List: {self}")
    while item:
        print(
            f"\t index: {index}\t data: {item.data}\t item: {item}\t pointer: {item._get_pointer()}"
            )
        item = item._get_pointer()
        index += 1

def _isleagl(self, node):
    if node is None:
        print(f"node' is None")
        return False
    elif type(node) != Node:
        print(f"'node' has worng type: {type(node)}")
        return False
    else:
        return True

def AppendNode(self, node):
    if self._isleagl(node):
        if self.list_start == None:
            self.list_start = node
            node._set_pointer(None)
        else:
            item = self.list_start
            while item:
                if item == node:
                    node = copy.deepcopy(node)
                elif item._get_pointer() is None:
                    item._set_pointer(node)

                    node._set_pointer(None)
                    break
                else:
                    item = item._get_pointer()

def DeleteNode(self, node):
    if self._islegal(node):
        if self.list_start == node:
            self.list_start = node._get_pointer()
        else:
            item = self.list_start
            while item:
                if item._get_pointer() == node:
                    item._set_pointer(node._get_pointer())
                break
            item = item._get_pointer()

Система меню: #i dont thinkэто очень поможет

def main():
my_list = None
my_node = None
while True:
    print("Node Manipulations")
    print("\t 0: Create Node")
    print("\t 1: Set Node Data")
    print("\t 2: Print Node")
    print()
    print("List Manipulations")
    print("\t 3: Create List")
    print("\t 4: Print List")
    print("\t 5: Append Node to List")
    print("\t 6: Delete Node from List")
    print()
    print("X: EXIT Program")
    choice = input("->")
    if choice not in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "X", "x"]:
        continue

    if choice == "X" or choice == "x":
         break

    elif choice == "0":
        my_node = Node()

    elif choice == "1":
        if my_node is None:
            print("Create Node first")
        else:
            my_node.data = input("Node Data? -> ")

    elif choice == "2":
        if my_node is None:
           print("Create Node first")
        else:
            my_node.PrintNode()

    elif choice == "3":
        my_list = LinkedList()

    elif choice == "4":
        if my_list is None:
           print("Create List first")
        else:
            my_list.PrintList()
            print()

    elif choice == "5":
        if my_list is None:
            print("Create List first")
        else:
            my_list.AppendNode(my_node)

    elif choice == "6":
        if my_list is None:
            print("Create List first")
        else:
            my_list.DeleteNode(my_node)

1 Ответ

0 голосов
/ 06 ноября 2019

Попробуйте запустить следующий код:

class K:
    pass

obj = K()
print(obj)

Вывод:

<__main__.K object at 0x01481FE8>

По умолчанию, если вы не пишете метод "в строку" (или __str__()) мусор выше - это то, что python будет выдавать в виде строки. Обратите внимание, что функция print может печатать только строки. Он не может печатать целые числа или что-то еще. Таким образом, print(n) преобразует все входные данные в строки перед их печатью. Приведенный ниже код описывает, что делает встроенная функция print:

import sys
def print(*args, sep=" ", end"\n", file=sys.stdout):
    file.write(sep.join(map(str, args)) + end) 

Итак, напишите свой собственный метод __str__:

import sys
import io
class Node:
    def __init__(self, data=None, pointer=None):
        self.data = data
        self.pointer = pointer

    def print_node(self, *, sep="\t", file=sys.stdout):
        print(
            f"Node Data: {self.data}",
            f"self: {id(self)}",
            f"pointer: {id(self.pointer)}",
            sep=sep,
            file=file
        )

    def _set_pointer(self, pointer):
        self.pointer = pointer

    def _get_pointer(self):
        return self.pointer

    def __str__(self):
        with io.StringIO() as string_stream:
            self.print_node(file=string_stream)
            stryng = string_stream.getvalue()
        return stryng

Ваш метод узла печати изначально называлсяPrintNode. Никогда не начинайте что-либо с заглавной буквы, если это не класс. Либо напишите printNode или print_node.

Во-вторых, я изменил f"pointer: {self.pointer}" на f"pointer: {id(self.pointer)}"

Предположим, что вы этого не сделали. Ну, тогда print_node напечатает self.pointer. Но self.pointer - это узел, поэтому он напечатает self.pointer.pointer. Но self.pointer.pointer - это узел, поэтому он напечатал бы self.pointer.pointer.pointer и так далее ... Вы этого не хотите. Адрес памяти объекта может быть получен с помощью функции id().

Кроме того, для print_node плохая идея напечатать себя. Это просто умолять о бесконечной рекурсии. Как мне распечатать self? хорошо, я печатаю data, self и pointer. Это означает, что я должен напечатать self, что означает, что я должен напечатать self, что означает, что я должен напечатать self, и так далее, всегда и всегда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...