【问题标题】:Least amount of syntatically correct characters to cause a Python exception导致 Python 异常的语法正确字符最少
【发布时间】:2020-05-05 19:39:06
【问题描述】:

这似乎会导致异常,例如在程序中进行快速和懒惰的编码中止不会 raise Exception。但是在快速开发过程中,更好的习惯用法可能是找到更方便的错误:

如果您清楚 IndexError[][0] 的占位符,您可以使用 5 个字符更快地完成此操作。

但是使用[]-0 和产生TypeError 的4 个字符可以做得更好。

现在我们将-[]+[] 改进为3 个字符,这也是TypeError。所有这些带有字符串和元组的变体都是可能的。

在 Python 中,语法上有效的代码是否可以抛出一个具有 2 个或更少字符且无依赖且独立的异常?这意味着不定义变量,并且可以在任何地方使用,因此不要使用任何单字母变量名称,否则 a 会抛出 NameError 但显然如果在程序中使用了 a 变量,它将无法工作。

我能找到的至少是上面的 3 个字符组合,这可能是一种非常快速和短手的开发时间,仅用于中止代码的快速测试。

更新:我想出了一个想法来详尽地回答这个问题,所以我继续这样做。诚然,这是一个代码高尔夫风格的问题,但它仍然很有趣。

【问题讨论】:

  • π 会导致 NameError 只要没有人使用 unicode 字符定义变量。 (显然,每个字符名称也都有效)
  • 不是 2 个字符的答案,但对我来说,3 个字符的明显解决方案是 1/0
  • 可以有多个 3 个字符:~1j~''*1,
  • 这个代码打高尔夫球的味道不仅仅是一个实际问题。

标签: python exception syntax


【解决方案1】:

要获得可以在其他地方跟踪的特定异常,您可以定义一个包含自定义异常类实例的单字母变量,该类在应用反转运算符时会引发自身:

class CustomError(Exception): 

    def __invert__(self):
        raise self  

É = CustomError()  # Unlikely to be used elsewhere single letter variable.

用法:

~É  ==> raises a CustomError exception

【讨论】:

    【解决方案2】:

    好的,所以我意识到这可以用一个详尽的 ASCII 字符枚举程序编写,该程序不仅易于编写,而且可以由 python 评估。然而,_ 关键字显然是 python 解释中的一个特殊符号,它是最后一个表达式的结果,因此必须在没有执行先前命令的新实例中运行(除了导入和函数定义)

    def py_try(num):
      import itertools
      combs = {'TypeError':[], 'ZeroDivisionError':[]}
      for item in itertools.product(range(256), repeat=num):
        try:
          eval(bytes(item))
        except SyntaxError: pass
        except NameError: pass
        except ValueError: pass
        except Exception as e:
          print(e.__class__.__name__ + " " + bytes(item).decode("ascii"))
          combs[e.__class__.__name__].append(bytes(item).decode("ascii"))
      return combs
    solution=py_try(3)
    len(solution['ZeroDivisionError']) #20
    len(solution['TypeError']) #168
    

    2 个字符永远不会起作用。但是使用 3 个字符,您会得到以下内容,为方便起见,它们表示为正则表达式(仅 []|- 的语法):

    [\-|+|~][\[\]|{}|\\|id|""|''] - TypeError 的 18 种可能组合。

    [0-9]/0[0-9]%0 中的任何一个都会产生 10+10 个 ZeroDivisionError 的组合。

    ~[0-9]j*[0-9],~[0-9].~.[0-9] 中的任何一个都会增加 10+10+10+10 种 TypeError 的可能性。

    [0-9]@[0-9] 中的任何一个,可产生 100 种 TypeError 的组合。

    [0-9]() 中的任何一个,在抛出 TypeError 之前给出 10 个组合,每个组合带有一个 SyntaxWarning: 'int' object is not callable; perhaps you missed a comma?

    所以 20 ZeroDivisionError 和 168 TypeError 是可能的。

    谁能想到只用 3 个字符就可以编写多达 188 个有保证的异常生成程序!

    【讨论】:

    • 干得好。但是 Python 不限于 ASCII,range(256) 也不是 ASCII 范围,因为 ASCII 是 7 位的。
    • 你是对的,实际上它只是使用 ASCII 进行单字节编码,它的全部 3 个字符组合。实际上,无效的 ASCII 范围被过滤为 ValueErrors。
    猜你喜欢
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 2016-07-21
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 2012-02-21
    • 2023-03-22
    相关资源
    最近更新 更多