【问题标题】:isinstance() not working the way I think it should [duplicate]isinstance() 没有按照我认为应该的方式工作[重复]
【发布时间】:2019-10-23 13:33:57
【问题描述】:

我的程序需要用户输入包含两个元素的列表,因此为了检查是否满足这些条件,我使用了以下代码:

start = input('Enter you start location.\nE.g. Enter "[2,5]" for x-coordinate 2 and y-coordinate  
             5.')
while isinstance(start, list) == False or len(start) != 2:
     start = input('Try again.')

无论我输入什么,这都不会退出 while 循环。为什么?

【问题讨论】:

  • input 将始终返回 str 对象。
  • 是什么让您认为您从输入中收到的数据是一个列表?很可能是字符串。所以这将使“2,5”是 3 个字符(不是 2)
  • @J.Murray 不太可能; 。如果start == '[2,5]'len(start) 将返回 5,而不是 3。
  • @mom'sSpaghettiCode 在 Python 2 中,input 确实会返回列表 [2, 5] 而不是字符串 '[2,5]'。这在 Python 3 中不再适用,它的 input 函数等效于 Python 2 的 raw_input

标签: python


【解决方案1】:

因为你的start 变量原来是一个字符串:start = "[2,5]",它不是一个列表。您可以要求用户输入例如2,3, 然后你得到"2,3"。然后,您可以使用start.split(',') 将其拆分为列表

【讨论】:

    【解决方案2】:

    绝对不推荐明显的安全风险,但你可以使用eval

    start = eval(input('Enter you start location.\nE.g. Enter "[2,5]" for x-coordinate 2 and y-coordinate 5.'))
    

    首选方法是使用拆分,但在这种情况下要求用户输入以逗号分隔的坐标。

    start = input('Enter you start location.\nE.g. Enter "2,5" for x-coordinate 2 and y-coordinate 5.')
    start = start.split(",")
    

    按照@soyapencil cmets 的建议进行编辑

    inp_str = input('Enter you start location.\nE.g. Enter "[2,5]" for x-coordinate 2 and y-coordinate 5.')
    start = [int(i) for i in iter(eval(inp_str,{}))]
    

    【讨论】:

    • 为了安全起见,我建议在本地绑定eval,如下所示:safe_parse = [int(i) for i in iter(eval(inp_str))],其中inp_str = input('Enter you start location.\nE.g. Enter "[2,5]" for x-coordinate 2 and y-coordinate 5.')
    • @soyapencil 为什么你认为这是安全的?对不受信任的输入绝对不安全
    • @juanpa.arrivillaga 哎呀!那个 sn-p 缺少一个空字典。现已修复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 2022-01-05
    • 2020-06-17
    • 2023-01-12
    • 2022-12-13
    • 2012-01-13
    相关资源
    最近更新 更多