【问题标题】:How would I adapt the file() function in Python2 to a Python3 function?如何使 Python2 中的 file() 函数适应 Python3 函数?
【发布时间】:2018-03-11 23:31:34
【问题描述】:

主要问题

我目前正在尝试在我的 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 中。现在我将如何用io.open 替换file(filename,'rb') 的确切行为?


对以下答案的回应

目前我尝试遵循@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)

【问题讨论】:

  • 你试过在代码上运行2to3吗?您不必让它为您自动修复代码,但将其差异作为建议阅读是非常有帮助的。在这种情况下,它应该建议使用open 代替file,这正是您需要开始的。
  • 实际上,未经测试……它可能建议。因为在 2.3-2.5 时代的某个地方,file 已经不是完全弃用但不鼓励支持open,而2to3 检查器假定您从惯用的 2.6 或 2.7 代码开始......
  • @abarnert 看看我上面的编辑。让我尝试运行 2to3
  • 您能向我们展示您尝试生成的代码吗?你有没有放弃'rb' 模式?在 Python 3 中,这意味着您希望使用默认编码将文件解码为 Unicode 文本,而这不适用于二进制文件。
  • @abarnert 请查看我的编辑,这可能会让我更清楚地了解我的尝试。

标签: python python-3.x macos io


【解决方案1】:

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

f=open(filename, 'rb')

请注意,与您的第二个版本不同,我没有删除 'rb' "mode" 参数。 b 表示“二进制模式”,它在 Python 3 中比在 Python 2 中更重要。没有它,你要求它将文件解码为 Unicode 文本(使用一些默认编码),这是行不通的处理二进制文件——它会给你类似问题后半部分的输出。


作为旁注,您可能希望像这样重写函数:

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

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

【讨论】:

    【解决方案2】:

    看来你至少有两个选择:

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

    b) 了解如何使用非常有用的 venv(虚拟 Python 环境)并使用 Python 2 解释器的实例为此项目创建运行时环境。

    如果你选择前者,你必须在调用open()时指定你正在尝试读取一个二进制文件:

    open(filename, 'rb')
    

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

    【讨论】:

    • 我在虚拟 Python 环境方面有过一些不好的经历,通常会尽量避免它们。您能否详细说明open()?我尝试用open() 简单地替换函数,但出现编码错误。
    • 我还通过上面的一些编辑扩展了我的担忧。
    • 你为什么不愿意使用venv
    • 好的,让我尝试使用venv 一次,我尝试使用penv 和 conda 一次,但无法正常工作。
    • pyenv project 包装了venv 可能会让您更适应 Python 虚拟环境。结合another, ancillary project by the same author,我开始依赖它来尝试各种解释器(不仅仅是 CPython 的版本)以及库的组合。
    猜你喜欢
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 2013-03-22
    • 2019-09-25
    • 2021-01-02
    • 2022-01-08
    相关资源
    最近更新 更多