noa*_*amt 5 python syntax keyword python-3.x
我想在Python中添加一个新的关键字,@ EliBendersky的精彩答案解释了如何通过更改代码和重新分发Python编译器来实现这一点.
是否可以在不更改编译器代码的情况下引入新关键字?也许通过图书馆介绍它?
编辑:
例如,我想通过添加像matches这样的关键字来添加正则表达式匹配的简写:
"You can't take the sky from me" matches '.+sky.+'
Run Code Online (Sandbox Code Playgroud)
我可以使用AST转换添加新的自定义行为,但上述情况将因语法错误而失败.
解析器是读取代码并决定哪些内容有意义、哪些内容无意义的工具/程序。尽管这是一个相当粗略的定义,但结果是该语言是由其解析器定义的。
ast解析器依赖于模块文档中指定的语言(形式)语法。
定义一个单纯的函数只是引入一个新特性而不修改语言,而添加一个关键字就等于引入一个新的语法,从而改变了语言的语法。
因此,从向语言添加新语法的意义上来说,添加新关键字不能在不更改语法语言的情况下进行,这需要编辑编译和执行链。
可能有一些聪明的方法来引入新功能,看起来像是新语法,但实际上只使用现有语法。例如,goto 模块依赖于该语言的一个不太为人所知的属性,即忽略限定标识符中点周围的空格。
你可以自己尝试一下:
>>> l = [1, 2, 3]
>>> l .append(4)
>>> l
[1, 2, 3, 4]
>>> l. append(5)
>>> l
[1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)
这允许使用以下内容,看起来像新语法,但实际上不是:
label .myLabel
goto .myLabel
Run Code Online (Sandbox Code Playgroud)
现在,该goto模块使用解释器内部工作的方式来执行从一个goto到给定的中断label......但这是另一个问题。
我想补充一点,Python 是一种思想非常开放的语言。它提供了大量很少使用的运算符,例如@. 该运算符是从 Python 3.5 引入的,主要用于矩阵乘法,并回退到对__matmul__. 我不得不说,我从来没有在代码中见过它。那么,为什么不将它用于您的目的呢?
让我们一步一步来做。我建议定义一个r类,它将充当正则表达式。
import re
class r:
def __init__(self, pattern):
self.regex = re.compile(pattern)
Run Code Online (Sandbox Code Playgroud)
现在,我希望能够将@运算符与此类一起使用,以及match字符串和字符串与模式之间的 a 语义。我将定义该__matmul__方法,如下所示:
class r:
def __matmul__(self, string):
return bool(self.regex.match(string))
Run Code Online (Sandbox Code Playgroud)
现在,我可以执行以下操作:
>>> r("hello") @ "hello"
True
>>> r("hello"] @ "world"
False
Run Code Online (Sandbox Code Playgroud)
相当不错,但还不是那样。我还将定义该__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
Run Code Online (Sandbox Code Playgroud)
现在,反向操作也可以工作:
>>> "hello" @ r("hello")
True
>>> "123456" @ r("\d+")
True
>>> "abc def" @ r("\S+$")
False
Run Code Online (Sandbox Code Playgroud)
这与您尝试的非常接近,只是我不必引入新的关键字!当然,现在r标识符必须受到保护,就像str或一样list......
| 归档时间: |
|
| 查看次数: |
117 次 |
| 最近记录: |