Python 实例化一个类会在循环时第二次给出可疑的结果

Python 实例化一个类会在循环时第二次给出可疑的结果,python,python-3.x,class,oop,Python,Python 3.x,Class,Oop,编辑: 首先,感谢@martineau和@Jornsharpe的及时回复。 起初我对写一篇冗长的描述犹豫不决,但现在我意识到为了简洁我牺牲了清晰度。(感谢@jornsharpe的链接) 因此,我试图尽可能简明扼要地描述我目前的情况: 我已经以python包的形式实现了Lempel-Ziv-Welch文本文件压缩算法。这是链接到 基本上,我在lzw.compress模块中有一个compress类,它接受文件名(和一组其他术语参数)作为输入,并生成压缩文件,然后由lzw.decompress模块中的

编辑: 首先,感谢@martineau和@Jornsharpe的及时回复。 起初我对写一篇冗长的描述犹豫不决,但现在我意识到为了简洁我牺牲了清晰度。(感谢@jornsharpe的链接)

因此,我试图尽可能简明扼要地描述我目前的情况:

我已经以python包的形式实现了Lempel-Ziv-Welch文本文件压缩算法。这是链接到

基本上,我在lzw.compress模块中有一个compress类,它接受文件名(和一组其他术语参数)作为输入,并生成压缩文件,然后由lzw.decompress模块中的decompress类解压生成原始文件

现在我要做的是压缩和解压缩一堆存储在目录中的不同大小的文件,并以图形方式保存和可视化压缩/解压缩所需的时间,以及压缩比和其他指标。为此,我将遍历文件名列表,并将其作为参数传递,以实例化compress类,并通过如下方式对其调用encode()方法开始压缩:

import os

os.chdir('/path/to/files/to/be/compressed/')

results = dict()
results['compress_time'] = []
results['other_metrics'] = []
file_path = '/path/to/files/to/be/compressed/'
comp_path = '/path/to/store/compressed/files/'
decomp_path = '/path/to/store/decompressed/file'
files = [_ for _ in os.listdir()]
for f in files:
    from lzw.Compress import compress as comp
    from lzw.Decompress import decompress as decomp

    c = comp(file_path+f,comp_path) #passing the input file and the output path for storing compressed file.
    c.encode()               
    #Then measure time required for comression using time.monotonic()

    del c
    del comp

    d = decomp('/path/to/compressed/file',decomp_path) #Decompressing
    d.decode()
    #Then measure time required for decompression using 
    #time.monotonic()
    #append metrics to lists in the results dict for this particular 
    #file

    if decompressed_file_size != original_file_size:
        print("error")
        break
    del d 
    del decomp
class trie():

def __init__(self):
    self.next = {}
    self.value = None
    self.addr = None

def insert(self, word=str(),addr=int()):
    node = self

    for index,letter in enumerate(word):
        if letter in node.next.keys():
            node = node.next[letter]
        else:
            node.next[letter] = trie()
            node = node.next[letter]
        if index == len(word) - 1:
            node.value = word
            node.addr = addr
def self_destruct(self):
    node = self

    if node.next == {}:
        return

    for i in node.next.keys():
        node.next[i].self_destruct()

    del node
我在没有for循环的情况下为每个文件独立运行了这段代码,并成功地实现了压缩和解压缩。因此,我希望压缩的文件没有问题

当我运行这个循环时,第一个文件(第一次迭代)成功运行,第二个文件的整个过程完成后,在下一次迭代中,“错误”被打印出来,循环退出。我曾尝试重新排序列表,甚至将其反转(可能某个特定的文件有问题),但没有任何效果

对于第二个文件/迭代,解压缩的文件内容可疑(与原始文件不匹配)。通常,解压缩后的文件大小几乎是原始文件大小的两倍。 我强烈怀疑这与类/包的变量在循环的不同迭代中以某种方式保持其状态有关。(为了解决这个问题,我删除了循环末尾的实例和类,如上面的代码片段所示,但没有成功。) 我还尝试在循环外导入类,但没有成功

p.S.:我是python新手,没有太多的专业知识,所以请原谅我在我的论述中没有“pythonic”,并提出了一个相当幼稚的问题

更新: 多亏了@martineau,其中一个问题是从另一个子模块导入全局变量。 但是,由于我对python3中的“del”操作符的肤浅了解,还有一个问题悄然出现。 我的程序中有这个数据结构,它基本上与二叉树相似。 我有一个自毁方法来删除树,如下所示:

import os

os.chdir('/path/to/files/to/be/compressed/')

results = dict()
results['compress_time'] = []
results['other_metrics'] = []
file_path = '/path/to/files/to/be/compressed/'
comp_path = '/path/to/store/compressed/files/'
decomp_path = '/path/to/store/decompressed/file'
files = [_ for _ in os.listdir()]
for f in files:
    from lzw.Compress import compress as comp
    from lzw.Decompress import decompress as decomp

    c = comp(file_path+f,comp_path) #passing the input file and the output path for storing compressed file.
    c.encode()               
    #Then measure time required for comression using time.monotonic()

    del c
    del comp

    d = decomp('/path/to/compressed/file',decomp_path) #Decompressing
    d.decode()
    #Then measure time required for decompression using 
    #time.monotonic()
    #append metrics to lists in the results dict for this particular 
    #file

    if decompressed_file_size != original_file_size:
        print("error")
        break
    del d 
    del decomp
class trie():

def __init__(self):
    self.next = {}
    self.value = None
    self.addr = None

def insert(self, word=str(),addr=int()):
    node = self

    for index,letter in enumerate(word):
        if letter in node.next.keys():
            node = node.next[letter]
        else:
            node.next[letter] = trie()
            node = node.next[letter]
        if index == len(word) - 1:
            node.value = word
            node.addr = addr
def self_destruct(self):
    node = self

    if node.next == {}:
        return

    for i in node.next.keys():
        node.next[i].self_destruct()

    del node
事实证明,这种类似C的对象递归删除在python中毫无意义,因为在这里,它在名称空间中的关联被删除,而真正的工作由垃圾收集器完成。 尽管如此,python为什么在创建新对象时仍保留变量的状态/关联还是有点奇怪(如编辑中我的循环片段所示)。 所以有两件事解决了这个问题。首先,我删除了全局变量,并将它们放在我需要它们的模块的本地(因此无需导入)。另外,我删除了trie的self_destruct方法,并简单地删除了:del rootwhere root=trie()


谢谢@martineau&@jornsharpe.

“结果很可疑”-这是什么意思?!请给出一个具体的例子,没有具体的例子,谁能知道发生了什么?我们至少需要看看
my_class
的定义-我怀疑这就是问题的根源。@jornsharpe,谢谢你的指导。我试图在编辑中澄清我的问题。谢谢。@martineau,我已经在编辑中提供了该软件包的链接。尽管如此,我不认为这门课有什么问题,因为我可以在每次运行一个文件而不是循环时获得我的结果。压缩和解压类使用dict.py中的dict、list和integer,但它们只被读取(或复制和编辑)。即使这样,我也无法理解,为什么每次删除和导入类及其实例之后,问题仍然存在。谢谢。Prathamesh:我不再认为是你的类(
compress
decompress
)造成了这个问题。这可能是因为您在
lzw.dicts
子模块脚本
dicts.py
中使用了全局变量。还要注意,删除模块并重新导入它们并不像您想象的那样工作,因为Python在
sys.modules
中缓存模块的方式。相反,您可以编写一个函数,将所有(可变)全局变量重置回初始状态,然后在处理每个文件之前调用该函数,从而解决问题。