Передача объектов с одинаковым именем в словарь изменяет старые объекты (передача по ссылке) - PullRequest
0 голосов
/ 20 мая 2019

Я создаю анализатор файловой системы, и у меня есть класс с именем HashableHeap, он переопределяет функцию __hash__ для хеширования с расширениями файлов.У меня есть словарь, который сопоставляет расширения с кучами.Например, .jpg куча должна содержать объекты jpg, и когда я хеширую для .jpg, она должна дать мне соответствующую кучу.

Проблема заключается в следующем: когда я сталкиваюсь с расширением, которое отсутствует в ключах словаря, я создаюновая куча и добавь ее.Когда код пытается создать и добавить новую кучу, он также модифицирует первую.Например: скажем, сначала добавляется куча .json к dict.затем он встречает файл .sql и создает новую кучу с тем же именем.Когда он добавляет новую кучу, файлы .sql также добавляются в кучу .json.Все кучи имеют одинаковое содержимое с разными ключами.

Я думаю, что речь идет о ссылках, я пытался удалить новый объект кучи, но он ничего не изменил.Возможно, мне нужно поведение типа pass by value, но я новичок в Python.

def add_to_dictionary(directory, abs_path):
    # Creates a file obj from path and adds to heap
    for file in directory:
        try:
            f = File(os.path.join(abs_path, file))
            if f.extension in extension_dictionary.keys():  # check if the corresponding heap exists for extension x
                hashable_heap = extension_dictionary[f.extension]
                hashable_heap.total_size += f.size
                heapq.heappush(hashable_heap.heap, f)
            elif f.extension != '':  # if the heap does not exist, create and add with current file
                new_heap = HashableHeap(f.extension)
                new_heap.total_size = f.size
                extension_dictionary[f.extension] = new_heap
                heapq.heappush(extension_dictionary[f.extension].heap, f)
        except FileNotFoundError:
            print(os.path.join(abs_path, file))
            print('No permission')

Вот код для HashableHeap, поскольку он запрашивается:

class HashableHeap:
    # wrapper class for heaps, required for the extension based hashing
    heap = []
    extension = ''
    total_size = 0

    def __init__(self, extension):
        self.extension = extension

    def __hash__(self):
        hash(self.extension)

    def __lt__(self, other):  # Comparator of the heaps by their sizes
        return self.total_size > other.total_size

PyCharm DebugСнимок экрана:

PyCharm Debug Screenshot

1 Ответ

1 голос
/ 20 мая 2019

Вы должны понимать разницу между переменными класса и переменными экземпляра.Переменные класса создаются вне функции __init__ и используются всеми экземплярами класса.Это редко то, что вы хотите.Переменные экземпляра создаются внутри функции __init__.Они уникальны для каждого экземпляра класса.

Вы создаете переменную heap вне метода __init__, поэтому она используется всеми экземплярами HashableHeap.Это именно то поведение, которое вы видите.

Попробуйте это:

class HashableHeap:
    # wrapper class for heaps, required for the extension based hashing
    def __init__(self, extension):
        self.heap = []
        self.total_size = 0
        self.extension = extension
 # Everything else is the same

Есть некоторые тонкости, касающиеся переменных класса и экземпляра.Когда вы присваиваете переменную, такую ​​как строка кода self.extension = extension, это фактически создает переменную экземпляра, которая скрывает переменную класса с тем же именем.Вам нужно прочитать об этом, если вы хотите полностью понять эту концепцию.

Кстати, ваша функция HashableHeap на самом деле не делает ничего полезного.Словари Python уже используют алгоритм хеширования для своих ключей автоматически.Когда вы вставляете пару ключ: значение в словарь, ключ хэшируется за вас.

...