python自加语句,在不自定义编译器的情况下向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?

Edit:

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.+'

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.

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.

However...

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.

You can try this by yourself:

>>> 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

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.

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?

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)

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

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

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...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值