我如何将Python2中的file()函数改编为Python3函数?

时间:2018-03-11 23:31:34

标签: python python-3.x macos io

主要问题

我目前正在尝试在Mac OS上运行this特定的Github项目。它肯定是为运行Python 2的系统编写的。但是,我正在运行Python3,我需要对程序进行一些修改。除下面的修改外,大多数修改都可以无缝地工作。

当我使用此命令运行程序时......

python3 separate_dsd.py -i ./../../Ricotti\ \&\ Alburquerque\ -\ Dont\ You\ Believe\ Me.mp3 -o ./ -m ./../../model1.pkl

...我收到错误NameError: name 'file' is not defined。文件已在Python3中替换为io.open。但是,只需用io.open替换函数调用就会给我一个错误。

特定行是代码块的f=file(filename,'rb')

def load_model(filename):
    f=file(filename,'rb')
    params=pickle.load(f)
    f.close()
    return params

它位于文件/DeepConvSep/examples/dsd100/separate_dsd.py中。现在,我将如何用file(filename,'rb')替换io.open的确切行为?

以下答案的回应

目前我尝试关注@ abarnert的建议并将我的代码更改为:

def load_model(filename):
    with open(filename, 'rb') as f:
        return pickle.load(f)

但我仍然得到错误:

Traceback (most recent call last):
  File "separate_dsd.py", line 336, in <module>
    main(sys.argv[1:])
  File "separate_dsd.py", line 333, in main
    train_auto(inputfile,outdir,model,0.3,30,25,32,513)
  File "separate_dsd.py", line 250, in train_auto
    params=load_model(model)
  File "separate_dsd.py", line 19, in load_model
    params=pickle.load(f)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xbb in position 2: ordinal not in range(128)

2 个答案:

答案 0 :(得分:2)

在Python 2.5(甚至可能更早)中已经不鼓励file构造函数支持open函数。在Python 3中,它被完全删除了。所以,它应该只是一个问题:

f=open(filename, 'rb')

请注意,与您的第二个版本不同,我没有删除'rb'&#34;模式&#34;论点。 b表示&#34;二进制模式&#34;,它在Python 3中比在Python 2中更重要。没有它,你要求它将文件解码为Unicode文本(使用一些默认编码),它不能与二进制文件一起使用 - 它会在你的问题的后半部分提供类似输出的内容。

作为旁注,您可能想要重写这样的函数:

def load_model(filename):
    with open(filename, 'rb') as f:
        return pickle.load(f)

这可以保证即使unpickling引发异常也会关闭文件。

答案 1 :(得分:1)

您似乎至少有两个选择:

a)将调用替换为file(),其中open()是Python 3中的内置函数

b)学习如何使用极其有用的venv(虚拟python环境),并使用Python 2解释器的实例为该项目创建运行时环境。

如果选择前者,则必须指定在致电open()时尝试读取二进制文件:

open(filename, 'rb')

但是,鉴于这可能不是本项目中唯一一个Python 3解释器与源代码不兼容的实例,我建议创建一个Python 2环境。