将具有相同名称的对象传递给字典是修改旧对象(通过引用传递)
Passing objects with same name to dictionary is modifying old objects (pass by reference)
我正在构建一个文件系统分析器,我有一个名为 HashableHeap
的 class,它会覆盖 __hash__
函数以使用文件扩展名进行哈希处理。我有一本将扩展映射到堆的字典。例如 .jpg 堆需要保存 jpg 对象,当我对 .jpg 进行哈希处理时,它应该给我相应的堆。
问题是:当我遇到不在字典键中的扩展时,我创建了一个新堆并添加了它。当代码尝试创建和添加新堆时,它也会修改第一个堆。例如:假设它首先向 dict 添加一个 .json 堆。然后它遇到一个 .sql 文件并创建一个同名的新堆。当它添加新堆时,.sql 文件也会添加到 .json 堆中。所有堆都是相同的内容,但键不同。
我认为这是关于引用的,我试图删除新的堆对象,但它没有任何改变。也许我需要像行为这样的价值传递,但我是 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调试截图:
您需要了解 class 变量和实例变量之间的区别。 Class 变量在 __init__
函数之外创建,并在 class 的所有实例之间共享。这很少是你想要的。实例变量在 __init__
函数中创建。它们对于 class.
的每个实例都是唯一的
您正在 __init__
方法之外创建变量 heap
,因此它由 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
class 与实例变量之间存在一些微妙之处。当您分配给一个变量时,例如您的代码行 self.extension = extension
,实际上会创建一个实例变量来隐藏同名的 class 变量。如果你想彻底理解这个概念,你需要阅读这篇文章。
顺便说一句,您的 HashableHeap 函数实际上没有做任何有用的事情。 Python 字典已经在其键上自动使用哈希算法。当您将 key:value 对插入字典时,密钥会为您散列。
我正在构建一个文件系统分析器,我有一个名为 HashableHeap
的 class,它会覆盖 __hash__
函数以使用文件扩展名进行哈希处理。我有一本将扩展映射到堆的字典。例如 .jpg 堆需要保存 jpg 对象,当我对 .jpg 进行哈希处理时,它应该给我相应的堆。
问题是:当我遇到不在字典键中的扩展时,我创建了一个新堆并添加了它。当代码尝试创建和添加新堆时,它也会修改第一个堆。例如:假设它首先向 dict 添加一个 .json 堆。然后它遇到一个 .sql 文件并创建一个同名的新堆。当它添加新堆时,.sql 文件也会添加到 .json 堆中。所有堆都是相同的内容,但键不同。
我认为这是关于引用的,我试图删除新的堆对象,但它没有任何改变。也许我需要像行为这样的价值传递,但我是 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调试截图:
您需要了解 class 变量和实例变量之间的区别。 Class 变量在 __init__
函数之外创建,并在 class 的所有实例之间共享。这很少是你想要的。实例变量在 __init__
函数中创建。它们对于 class.
您正在 __init__
方法之外创建变量 heap
,因此它由 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
class 与实例变量之间存在一些微妙之处。当您分配给一个变量时,例如您的代码行 self.extension = extension
,实际上会创建一个实例变量来隐藏同名的 class 变量。如果你想彻底理解这个概念,你需要阅读这篇文章。
顺便说一句,您的 HashableHeap 函数实际上没有做任何有用的事情。 Python 字典已经在其键上自动使用哈希算法。当您将 key:value 对插入字典时,密钥会为您散列。