【问题标题】:How should I write my application that makes use of `raw_input` to work with Python 2.x and 3.x?我应该如何编写使用 `raw_input` 来使用 Python 2.x 和 3.x 的应用程序?
【发布时间】:2014-08-19 18:15:13
【问题描述】:

我看到一些代码(例如this tutorial from dropbox)可能需要在 Python 2.X 上运行相当长时间,但也可能在 Python 3.X 上运行

那些项目应该如何处理raw_input

我觉得有点像

#!/usr/bin/env python


def input_string(question=""):
    """A function that works for both, Python 2.x and Python 3.x.
       It asks the user for input and returns it as a string.
    """
    import sys
    if sys.version_info[0] == 2:
        return raw_input(question)
    else:
        return input(question)

# Example
answer = input_string("What is your name? ")
print(answer)

可能是个好方法,但我不太确定。

是否有“官方”建议(例如以 PEP 的形式)如何处理? 现在是怎么做到的?

【问题讨论】:

  • 另外,请注意此处的建议:stackoverflow.com/a/5868543/716118。一种替代方法是简单地在 Python 2.x 中编写您的应用程序,然后使用 2to3 进行转换。
  • 2to3 确实将源代码从 2.x Python 代码更改为 3.x Python 代码。如果我错了,请纠正我,但生成的代码将不再适用于 Python 2.x。那不是我想要的。我想要同时适用于 Python 2 和 Python 3 的代码。
  • 您希望相同的脚本在 2.x 和 3.x 中都可以工作吗?

标签: python python-2.7 python-3.x project-management


【解决方案1】:

这个怎么样?

try: 
    input = raw_input
except NameError: 
    pass
print("Hi " + input("Say something: "))

【讨论】:

  • python 2.x 中有input,而你只是覆盖了它。
  • 我通常会这样做,但会用别的名字,比如input_func。然后,我分配 input 而不是 except 块下的 pass。与下面的答案相比,这具有以下答案的优势,即文件顶部只需要一次尝试/除外,而不是每次需要用户输入时都需要一次。
  • @J0HN 所以?这正是 OP 想要的。 Python 2.x input邪恶的。你从不想要使用它。 99% 的时间你想使用 int(raw_input())float(raw_input()) 之类的东西,另外 0.99% 的时间你想使用 ast.literal_eval(raw_input()) 并且仅在你真正想要的 0.001% 的用法中使用 eval(raw_input()) [即input 做了什么]。
  • @Bakuriu,感谢您非常激动的评论。是的,我知道这种行为,不,我不认为它是覆盖内置函数的借口。不,这是解决 OP 问题的一种可能解决方案,但不是完全所要求的。
  • @J0HN 除了 OP 覆盖内置。要覆盖你会做的内置:try: __builtins__.input = raw_input; except NameError: pass。此答案中的解决方案创建了一个名为input全局变量。它不会与其他模块混淆,因此使用起来非常安全。事实上,它强制执行一种良好的做法。
【解决方案2】:

你有几个选择

选项 1 - 只需使用 2to3

2to3 是一个 python 程序,可以适当地转换你的程序,解决这个问题

从上面的链接:

这是一个示例 Python 2.x 源文件,example.py:

def greet(name):
    print "Hello, {0}!".format(name)
print "What's your name?"
name = raw_input()
greet(name)

可以在命令行通过2to3转换成Python 3.x代码:

$ 2to3 example.py 

打印与原始源文件的差异。 2to3 也可以将所需的修改直接写回源代码 文件。 (除非还给出了 -n,否则会备份原始文件。) 使用 -w 标志启用写回更改:

$ 2to3 -w example.py 

改造后的example.py是这样的:

def greet(name):
    print("Hello, {0}!".format(name)) 
print("What's your name?") 
name = input() 
greet(name)

选项 2 - 使用 try/except

try:
    return raw_input(question)
except NameError:
    return input(question)

这将帮助您避免每次更改某些内容时都必须重新运行 2to3。为了避免这样做令人作呕,您可以将它放在这样的函数中

def real_input(astring=""):
    try:
        return raw_input(astring)
    except NameError:
        return input(astring)

然后在需要用户输入时使用real_input()

【讨论】:

  • 这个答案的三个大问题。 (1.) 您可以很容易地做到这一点,而无需使用转换器工具,使用与两个版本的 Python 兼容的相同脚本。 (2.) 您的“选项 2”需要在任何地方都尝试/除外,而不是在顶部。 (3.) 你甚至都没有费心去弄清楚 WhateverErrorThisIs 在 Python 解释器中需要 2 秒。
  • @Two-BitAlchemist 关于 (1.) 这就是我提供另一个选项的原因(并且 OP 不清楚可能需要更改什么以使其兼容)。 (2.) 我打算将选项 2 放在一个函数中(例如 OP 提供的函数),然后调用该函数而不是 raw_input()input() (3.) 公平点。我的机器上没有 Python 3,也没有时间查找它
猜你喜欢
  • 2019-10-07
  • 2012-07-01
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-26
  • 2015-05-16
相关资源
最近更新 更多