不改变语言就不能引入新的关键字
解析器是读取代码的工具/程序,它决定什么是有意义的,什么是没有意义的。
虽然这是一个相当粗略的定义,但其结果是该语言由其解析器定义。
解析器依赖于ast module documentation 中指定的语言(正式)语法。
虽然定义一个单纯的函数只是引入了一个新特性而不修改语言,但是添加一个关键字就等于引入了一种新的语法,这反过来又改变了语言的语法。
因此,在不改变语法的语言的情况下,添加一个新的关键字,在向一种语言添加新语法的意义上是不可能的,这需要编辑编译和执行链。
但是……
可能有一些聪明的方法来引入一个新特性,它看起来像一个新的语法,但实际上只使用现有的语法。
例如,goto module 依赖于该语言的一个不太为人所知的属性,即忽略限定标识符中点周围的空格。
你可以自己试试这个:
>>> l = [1, 2, 3]
>>> l .append(4)
>>> l
[1, 2, 3, 4]
>>> l. append(5)
>>> l
[1, 2, 3, 4, 5]
这允许使用以下内容,看起来像一种新语法,但实际上不是:
label .myLabel
goto .myLabel
现在,goto 模块使用解释器内部的工作方式来执行从一个goto 到给定label 的中断...
但这是另一个问题。
我想补充一点,Python 是一种思想开放的语言。
它提供了大量很少使用的运算符,例如@。
这个从 Python 3.5 引入的运算符主要用于矩阵乘法,并回退到对 __matmul__ 的调用。
我不得不说,我从未在代码中见过它。
那么,为什么不将它用于您的目的呢?
让我们一步一步来。
我建议定义一个r 类,它的行为就像一个正则表达式。
import re
class r:
def __init__(self, pattern):
self.regex = re.compile(pattern)
现在,我希望能够将 @ 运算符与此类一起使用,并与字符串一起使用,在字符串和模式之间具有 match 的语义。
我将定义__matmul__方法,如下:
class r:
def __matmul__(self, string):
return bool(self.regex.match(string))
现在,我可以执行以下操作:
>>> r("hello") @ "hello"
True
>>> r("hello"] @ "world"
False
相当不错,但还没有。
我还将定义__rmatmul__ 方法,因此它只是回退到对__matmul__ 的调用。
最后,r 类看起来像这样:
class r:
def __init__(self, pattern):
self.regex = re.compile(pattern)
def __matmul__(self, string):
return bool(self.regex.match(string))
def __rmatmul__(self, string):
return self @ string
现在,反向操作也可以了:
>>> "hello" @ r("hello")
True
>>> "123456" @ r("\d+")
True
>>> "abc def" @ r("\S+$")
False
这与您尝试的非常接近,除了我不必引入新关键字!
当然,现在必须保护r 标识符,就像str 或list...