在Python2.7中运行的代码与Python3.5.1的代码不同

在Python2.7中运行的代码与Python3.5.1的代码不同,python,python-3.x,Python,Python 3.x,我的Python代码在Python 2.7中运行良好,但在Python 3中运行时,它无法正常工作: import sys, os, hashlib dir_name = sys.argv[1] # Get the total number of args passed to the crawler.py and set default # directory def check_arguments(): global dir_name total = len(sys.arg

我的Python代码在Python 2.7中运行良好,但在Python 3中运行时,它无法正常工作:

import sys, os, hashlib

dir_name = sys.argv[1]

# Get the total number of args passed to the crawler.py and set default
# directory
def check_arguments():
    global dir_name
    total = len(sys.argv)
    if total > 2:
        print("Bitte geben Sie nur ein Argument als Startverzeichnis an.")
        sys.exit()
    elif total == 2:
        try:
            os.listdir(dir_name)
            print("Startverzeichnis " + dir_name + " wird verwendet.")
        except:
            print("Geben Sie ein gültiges Startverzeichnis an.")
            sys.exit()
    else:
        print("Startverzeichnis /tmp wird verwendet.")
        dir_name = '/tmp'

def create_MD5(dir_name):
    file_list = []
    hash_list = []
    for file in os.listdir(dir_name):
        try:
            if os.path.isfile(os.path.join(dir_name, file)):
                print("Folgende Datei gefunden: " , os.path.join(dir_name, file))
                file_list.append(file)
                hash = hashlib.md5.new()
                f = open(os.path.join(dir_name, file),'rb')
                hash.update(f.read())
                f.close()
                hash_list.append(hash.digest())

            elif os.path.isdir(os.path.join(dir_name, file)):
                print("Folgendes Verzeichnis gefunden:", os.path.join(dir_name, file))
                #print_files()
                fl, hl = create_MD5(os.path.join(dir_name, file))
                for i in fl:
                    file_list.append(i)
                for i in hl:
                    hash_list.append(i)
            else:
                pass
        except:
            print("Fehlende Zugriffsrechte")

    return file_list, hash_list

def print_MD5():
    fl, hl = create_MD5(dir_name)
    for i in range(len(fl)):
        print(os.path.join("Die Datei ", '%-22s  hat folgenden MD5-Hash: %s' % (fl[i], hl[i])))

check_arguments()
print_MD5()
在控制台中,我得到:

Traceback (most recent call last):
  File "crawler.py", line 77, in <module>
    print_MD5()
  File "crawler.py", line 74, in print_MD5
    print(os.path.join("Die Datei ", '%-22s  hat folgenden MD5-Hash: %s' % (fl[i], hl[i])))
IndexError: list index out of range
回溯(最近一次呼叫最后一次):
文件“crawler.py”,第77行,在
打印_MD5()
文件“crawler.py”,第74行,在print_MD5中
打印(os.path.join(“Die Datei”,'-22s hat folgenden MD5哈希:%s'(fl[i],hl[i]))
索引器:列表索引超出范围

如何更改代码,使其也能与Python 3一起运行?

您的“f1”列表比“h1”列表长

从代码中很难看出它是如何达到这种状态的。我的猜测是,在调用文件\u list.append()之后的某个时刻,您在调用hash\u list.append()之前遇到了一个异常。可能在“f=open(…)”行中

重构create_MD5代码,确保两个附录之间没有异常发生,并且应该得到修复

编辑 至于这在2.7而不是3.5中起作用的原因。我的猜测是,它与以下来自

作为文本文件打开的文件(仍然是open()的默认模式)始终使用编码在字符串(内存中)和字节(磁盘上)之间映射。二进制文件(在模式参数中以b打开)总是使用内存中的字节。这意味着,如果使用不正确的模式或编码打开文件,I/O很可能会大声失败,而不是默默地生成不正确的数据


或者,更可能的情况是——见杰克的答案。

您的“f1”列表比“h1”列表长

从代码中很难看出它是如何达到这种状态的。我的猜测是,在调用文件\u list.append()之后的某个时刻,您在调用hash\u list.append()之前遇到了一个异常。可能在“f=open(…)”行中

重构create_MD5代码,确保两个附录之间没有异常发生,并且应该得到修复

编辑 至于这在2.7而不是3.5中起作用的原因。我的猜测是,它与以下来自

作为文本文件打开的文件(仍然是open()的默认模式)始终使用编码在字符串(内存中)和字节(磁盘上)之间映射。二进制文件(在模式参数中以b打开)总是使用内存中的字节。这意味着,如果使用不正确的模式或编码打开文件,I/O很可能会大声失败,而不是默默地生成不正确的数据

或者,更可能的情况是——见杰克的答案。

行:

hashlib.md5.new()
不正确,应为:

hashlib.md5()
这是抛出一个错误,您的异常处理代码正在处理该错误。这就是为什么一个通用的
,除了:
,不管它是什么都继续是一个坏主意,特别是在像您这样的情况下,这可能会使程序处于一个坏状态

我不知道为什么它在2.7上工作,但我怀疑它可能没有做你认为它正在做的事情

此外,由于3.x中的hashlib在创建散列时会重新设定散列的种子,因此最好使用已知散列创建一个实例。

行:

hashlib.md5.new()
不正确,应为:

hashlib.md5()
这是抛出一个错误,您的异常处理代码正在处理该错误。这就是为什么一个通用的
,除了:
,不管它是什么都继续是一个坏主意,特别是在像您这样的情况下,这可能会使程序处于一个坏状态

我不知道为什么它在2.7上工作,但我怀疑它可能没有做你认为它正在做的事情


此外,由于3.x中的hashlib在创建散列时会重新设定散列的种子,因此最好使用已知散列创建一个实例。

堆栈跟踪是程序生成的唯一输出吗?特别是,它是否在这一点之前打印过“Fehlende Zugriffsrechte”?
print\u MD5
使用全局
dir\u名称,但没有声明它是这样的。您能否在
print(fl)
print(hl)
中的
循环之前添加行
for
print\u MD5()
查看哪个列表导致了问题?@ScottHunter,没关系。
global
语句仅在您希望为全局名称分配某些内容时才是必需的。
hl
似乎比
fl
短。堆栈跟踪是程序生成的唯一输出吗?特别是,它是否在这一点之前打印过“Fehlende Zugriffsrechte”?
print\u MD5
使用全局
dir\u名称,但没有声明它是这样的。您能否在
print(fl)
print(hl)
中的
循环之前添加行
for
print\u MD5()
查看哪个列表导致了问题?@ScottHunter,没关系。
global
语句仅在您希望为全局名称分配某些内容时才是必需的。
hl
似乎比
fl
短。我同意这是问题的最可能原因,但是我很好奇为什么它只发生在3.5中,而不是2.7中。在2.7中我使用了md5,在3中我删除了导入md5。我同意这是问题最可能的原因,但我很好奇为什么它只发生在3.5中,而不是在2.7中。在2.7中我使用了md5,在3中我删除了导入md5