什么是可移植的方式 (python 2/python 3) 在提供默认答案的同时询问用户?
What would be a portable way (python 2/python 3) to interrogate the user while providing a default answer?
我想问用户一个有默认答案的问题,例如:
How many apples do you want? [default 40]: 50
You have requested 50 apples.
如何以整洁、健壮的方式对其进行编码,以便在 Python 2 和 3 中使用?如何让默认值的显示方式看起来像上面显示的那样?
我有以下尝试的开始:
def interrogate_with_default(
prompt = None,
default = None
):
readline.set_startup_hook(lambda: readline.insert_text(default))
#readline.set_startup_hook(lambda: readline.insert_text(
# " [default: {default}]: ".format(
# default = default
# )
#))
try:
return get_input(prompt)
finally:
readline.set_startup_hook()
def get_input(
prompt = None
):
if sys.version_info >= (3, 0):
return input(prompt)
else:
return raw_input(prompt)
number_of_apples = interrogate_with_default(
prompt = "How many apples do you want?",
default = "40"
)
这样可以吗?
my_input = int(input("How many apples do you want? [default 40]: ") or "40")
您可以使用 or
为用户未输入任何内容的情况提供默认值(因为结果是一个空字符串,evaluates false-y):
>>> 'foo' or 'bar'
'foo'
>>> '' or 'bar'
'bar'
将其集成到您可以实际使用的函数中(!r
用于调用 __repr__
,以便例如字符串包含引号):
try:
input = raw_input
except NameError:
pass
def interrogate(prompt, default=None):
"""Ask the user to enter a value (or accept optional default)."""
if default is None:
return input('{}: '.format(prompt))
return input('{} [default {!r}]: '.format(prompt, default)) or default
注意遵守 the style guide and an "easier to ask forgiveness than permission" 跨 Python 2.x 和 3.x 工作的方法。虽然这确实掩盖了 2.x 中的一个内置函数(有些人显然认为这是一种不好的做法),但无论如何你都不应该真正使用它(pylint
称它为糟糕的内置函数,事实上!)并使编写 3.x 风格的代码变得更容易,这些代码将在 2.x 中继续 运行。另一种方法是在这两种情况下都使用别名,例如:
try:
get_input = raw_input
except NameError:
get_input = input
然后到处使用get_input
;如果您将 2.x 和 3.x 视为同等重要,这可能更合适。
如果问题的重点是与 python 2 和 python 3 的兼容性,答案是:不要以临时方式做!有很多事情要注意。如果您无法避免必须支持多个平台,请选择一个专为此目的而设计的库并始终如一地使用它。我相信 six
是当前的技术水平:
from __future__ import print_function
import six
然后使用six.moves.input()
读取用户输入。它在 python 2 上绑定到 raw_input
,在 python 3 上绑定到常规 input
。所以基本上你会编写一个 python 3 程序,具有兼容性模块顶部的管道。
备选方案: 你可以写 from six.moves import input
,它在 python 2 上使 input()
表现得像 raw_input()
。这允许更多 "native" python 3 代码,但如果您使用 python 2 规范阅读它会造成混淆。我想如果代码 一致 在 python 3 样式中是安全的。
对于默认设置部分,请保持明确,以便您轻松理解和调试。我喜欢提前设置默认值。然后我会简单地阅读一个答案,如果它是非空的(并且有效)就使用它
apples = 40
...
response = six.moves.input("How many apples do you want? [%d]: " % apples).strip()
if response:
apples = int(response)
与建议的 input("...") or 40
技巧相比,此设置的优点是您可以进一步验证并忽略负值、分数值、键盘组合以及通常不适合的任何内容您要问的特定问题(生活中有比非负整数更多的东西)。
在这种情况下,您可以使用 try-except 块轻松丢弃非整数值:
if response:
try:
apples = int(response)
except ValueError:
pass
我想问用户一个有默认答案的问题,例如:
How many apples do you want? [default 40]: 50
You have requested 50 apples.
如何以整洁、健壮的方式对其进行编码,以便在 Python 2 和 3 中使用?如何让默认值的显示方式看起来像上面显示的那样?
我有以下尝试的开始:
def interrogate_with_default(
prompt = None,
default = None
):
readline.set_startup_hook(lambda: readline.insert_text(default))
#readline.set_startup_hook(lambda: readline.insert_text(
# " [default: {default}]: ".format(
# default = default
# )
#))
try:
return get_input(prompt)
finally:
readline.set_startup_hook()
def get_input(
prompt = None
):
if sys.version_info >= (3, 0):
return input(prompt)
else:
return raw_input(prompt)
number_of_apples = interrogate_with_default(
prompt = "How many apples do you want?",
default = "40"
)
这样可以吗?
my_input = int(input("How many apples do you want? [default 40]: ") or "40")
您可以使用 or
为用户未输入任何内容的情况提供默认值(因为结果是一个空字符串,evaluates false-y):
>>> 'foo' or 'bar'
'foo'
>>> '' or 'bar'
'bar'
将其集成到您可以实际使用的函数中(!r
用于调用 __repr__
,以便例如字符串包含引号):
try:
input = raw_input
except NameError:
pass
def interrogate(prompt, default=None):
"""Ask the user to enter a value (or accept optional default)."""
if default is None:
return input('{}: '.format(prompt))
return input('{} [default {!r}]: '.format(prompt, default)) or default
注意遵守 the style guide and an "easier to ask forgiveness than permission" 跨 Python 2.x 和 3.x 工作的方法。虽然这确实掩盖了 2.x 中的一个内置函数(有些人显然认为这是一种不好的做法),但无论如何你都不应该真正使用它(pylint
称它为糟糕的内置函数,事实上!)并使编写 3.x 风格的代码变得更容易,这些代码将在 2.x 中继续 运行。另一种方法是在这两种情况下都使用别名,例如:
try:
get_input = raw_input
except NameError:
get_input = input
然后到处使用get_input
;如果您将 2.x 和 3.x 视为同等重要,这可能更合适。
如果问题的重点是与 python 2 和 python 3 的兼容性,答案是:不要以临时方式做!有很多事情要注意。如果您无法避免必须支持多个平台,请选择一个专为此目的而设计的库并始终如一地使用它。我相信 six
是当前的技术水平:
from __future__ import print_function
import six
然后使用six.moves.input()
读取用户输入。它在 python 2 上绑定到 raw_input
,在 python 3 上绑定到常规 input
。所以基本上你会编写一个 python 3 程序,具有兼容性模块顶部的管道。
备选方案: 你可以写 from six.moves import input
,它在 python 2 上使 input()
表现得像 raw_input()
。这允许更多 "native" python 3 代码,但如果您使用 python 2 规范阅读它会造成混淆。我想如果代码 一致 在 python 3 样式中是安全的。
对于默认设置部分,请保持明确,以便您轻松理解和调试。我喜欢提前设置默认值。然后我会简单地阅读一个答案,如果它是非空的(并且有效)就使用它
apples = 40
...
response = six.moves.input("How many apples do you want? [%d]: " % apples).strip()
if response:
apples = int(response)
与建议的 input("...") or 40
技巧相比,此设置的优点是您可以进一步验证并忽略负值、分数值、键盘组合以及通常不适合的任何内容您要问的特定问题(生活中有比非负整数更多的东西)。
在这种情况下,您可以使用 try-except 块轻松丢弃非整数值:
if response:
try:
apples = int(response)
except ValueError:
pass