在不自定义编译器的情况下向Python添加新语句 [英] Add new statements to Python without customizing the compiler

查看:108
本文介绍了在不自定义编译器的情况下向Python添加新语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Python中添加一个新关键字,然后@EliBendersky的妙妙的答案解释了如何通过更改来做到这一点代码并重新分发Python编译器.

I'd like to add a new keyword to Python and @EliBendersky's wonderful answer explains how to do this by changing the code and re-distributing the Python compiler.

是否可以在不更改编译器代码的情况下引入新的关键字 ?也许通过图书馆介绍它?

Is it possible to introduce a new keyword without changing the compiler code? Perhaps introduce it through a library?

例如,我想通过添加类似matches这样的关键字来为正则表达式匹配添加简写:

For example, I'd like to add a shorthand for regex matching by adding a keyword like matches that can be used like:

"You can't take the sky from me" matches '.+sky.+'

我可以使用AST转换添加新的自定义行为,但是上述情况将由于语法错误而失败.

I can add new, custom behavior using AST transformations, but the above case will fail on a syntax error.

推荐答案

一个人不能在不更改语言的情况下引入新关键字

解析器是一种工具/程序,它可以读取代码,并确定有意义的内容和无效的内容. 尽管这是一个粗略的定义,但其结果是该语言由其解析器进行了定义.

One cannot introduce a new keyword without changing the language

The parser is the tool/program that reads through the code, and decides what makes sense and what doesn't. Although it's a rather coarse definition, the consequence is that the language is defined by its parser.

解析器依赖于 ast模块文档.

The parser relies on the language's (formal) grammar, specified in the ast module documentation.

虽然仅定义函数只是引入了一项新功能而没有修改语言,但是添加关键字无异于引入一种新语法,这反过来又改变了该语言的语法.

While defining a mere function only introduces a new feature without modifying the language, adding a keyword is tantamount to introducing a new syntax, which in turn changes the language's grammar.

因此,在不改变语法语言的情况下,就不能在语言中添加新的语法,这需要编辑编译和执行链.

Therefore, adding a new keyword, in the sense of adding a new syntax to a language, cannot be made without changing the grammar's language, which requires editing the compilation and execution chain.

可能有一些聪明的方法来引入新功能,这些功能看起来像新语法,但实际上仅使用现有语法. 例如, goto模块依赖于一种不太知名的语言属性,即合格标识符中的点周围的空格将被忽略.

There might be some smart ways to introduce a new feature, that looks like a new syntax but in fact only uses the existing syntax. For instance, the goto module relies on a not-so-well-known property of the language, that the spaces around a dot in a qualified identifier are ignored.

您可以自己尝试:

>>> l = [1, 2, 3]
>>> l    .append(4)
>>> l
[1, 2, 3, 4]
>>> l.    append(5)
>>> l
[1, 2, 3, 4, 5]

这允许使用以下形式,看起来像新语法,但实际上不是:

This allows using the following, that looks like a new syntax, but really is not:

label .myLabel
goto .myLabel

现在,goto模块使用解释器内部工作的方式来执行从一个goto到给定label的中断... 但这是另一个问题.

Now, the goto module uses the way the interpreter internally works to perform break from one goto to a given label... But that's another problem.

我想补充一点,Python是一种开放的语言. 它提供了大量很少使用的运算符,例如@. 此运算符是从Python 3.5引入的,主要用于矩阵乘法,并且回溯到对__matmul__的调用. 我不得不说,我从未在代码中看到它. 那么,为什么不为您的目的使用它呢?

I'd like to add that Python is quite an open-minded language. It provides a nice amount of seldom used operators, for instance, @. This operator, introduced from Python 3.5, was primarily meant for matrix multiplication, and falls back to a call to __matmul__. I have to say, I've never seen it in code. So, why not use it for your purpose?

让我们一步一步地做. 我建议定义一个r类,该类将充当正则表达式.

Let's do it step-by-step. I propose to define a r class, that will behave as a regex.

import re

class r:
    def __init__(self, pattern):
        self.regex = re.compile(pattern)

现在,我希望能够对此类使用@运算符以及一个字符串,并且在字符串和模式之间使用match的语义. 我将定义__matmul__方法,如下所示:

Now, I want to be able to use the @ operator with this class, together with a string, with the semantic of a match between the string and the pattern. I'll define the __matmul__ method, just as follows:

class r:
    def __matmul__(self, string):
        return bool(self.regex.match(string))

现在,我可以执行以下操作:

Now, I can do the following:

>>> r("hello") @ "hello"
True
>>> r("hello"] @ "world"
False

很好,但是还不行. 我还将定义__rmatmul__方法,因此它只是回退到__matmul__的调用. 最后,r类如下所示:

Pretty nice, but not that yet. I'll define the __rmatmul__ method as well, so it merely falls back to a call to __matmul__. In the end, the r class looks like this:

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

现在,反向操作也可以工作:

Now, the reverse operation works as well:

>>> "hello" @ r("hello")
True
>>> "123456" @ r("\d+")
True
>>> "abc def" @ r("\S+$")
False

这与您的尝试非常接近,除了,我不必引入新的关键字! 当然,现在r标识符必须受到保护,就像strlist ...

This is very near from what you were attempting, except, I didn't have to introduce a new keyword! Of course, now the r identifier must be protected, just like str or list...

这篇关于在不自定义编译器的情况下向Python添加新语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆