椭圆形Python编程
Elliptical Python Programming

原始链接: https://susam.net/elliptical-python-programming.html

苏萨姆·帕尔以幽默的笔调探索了Python编程中非常规的、反直觉的编码方式,强调了这门语言中内在的“禅意”。他展示了如何使用布尔比较,例如 `(...==...)`,来表示数字,滑稽地提倡这种不寻常的风格。他展示了即使是一个简单的“Hello, World!”程序,也可以只用这种方法构建,将其变成一堆难以阅读的点、括号和字符代码的乱码。 他讽刺地建议重新映射Tab键,以便更容易地输入省略号,甚至提供了一个使用空括号的替代版本。他承认这种代码不适合用于生产环境,建议在出现问题时使用日志进行调试。这篇文章最终是对过于复杂或难以阅读的代码的轻松批判,将其与Python的清晰性和可读性原则形成对比,告诫不要将Python变成古老的召唤仪式。作者开玩笑地鼓励,然后又劝退读者在生产环境中练习奇怪的编码技巧,从而突出了在Python中*不应该*做什么。

Hacker News上关于“椭圆形Python编程”的讨论探索了`...`(省略号)对象的使用。一位评论者解释说`...`主要是一个占位符,等于自身,并且Python的隐式类型转换允许包含它的不寻常的算术表达式。表达式`--(...==...)--(...==...)` 通过利用布尔值到整数的转换以及前缀和中缀否定运算符的行为计算结果为2。讨论强调了在算术运算中`True`变成`1`,减去负数与加法相同。另一位用户观察到,在Python中,`1--2==3` 是一个有效的表达式。另一位用户指出这不是Python特有的运算,而是带有符号分配的一般算术运算。

原文

By Susam Pal on 10 Apr 2025

One thing I love about Python is how it comes with its very own built-in zen. In moments of tribulations, when I am wrestling with crooked code and tangled thoughts, I often find solace in its timeless wisdom. Here's a glimpse of the clarity it provides:

$ python3 -m this | grep e-
There should be one-- and preferably only one --obvious way to do it.

Indeed, there is one and only one obvious way to write the number 1 in Python, like so:

>>> --(...==...)
1

You may, quite naturally, place several ones adjacently to produce larger integers:

>>> --(...==...)--(...==...)
2

And so on, ad infinitum, or until your heap collapses like a poorly made soufflé. Now, the "pre-decrement operator" at the beginning is entirely optional, much like the plus sign when you write "+5 biscuits" in a letter to your grandmother. It's not wrong, but it is unnecessary and, frankly, a bit pretentious. So unless you want to look peculiar to your colleagues, you would likely want to adopt a more conventional style, such as this:

>>> (...==...)--(...==...)--(...==...)
3

Now, all computer programs are, in some sense, just a long, earnest stream of bits. It is currently fashionable to bundle these bits into groups of eight and write them as integers. Following this trend, we can compute absolutely anything that is computable as long as we know exactly what integers to write. Now, I wouldn't want to bore you with the finer details of computer science – not in this day and age – fascinating as they may be. I trust you are quite capable of drawing the rest of the f... well, feathered, nocturnal bird. Once you've grasped the basics, a typical first Python program might look something like this:

exec('%c'*((...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))%(((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)),((...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...))**((...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...))--((...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...))--((...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...))--(...==...),*(((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...))**((...==...)--(...==...)--(...==...)),)*((...==...)--(...==...)),((...==...)--(...==...)--(...==...))**((...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)),((...==...)--(...==...))**((...==...)--(...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...))**((...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...))**((...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...))--((...==...)--(...==...)--(...==...)),((...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...))--(...==...)))

Now you might be wondering if this is really the way one ought to write production Python code. Isn't it too much trouble to type those dots over and over again? Not if you remap your tab key to type three dots, of course. But I understand not everyone likes to remap their keys like this. In particular, there exists a peculiar species of mammal known to remap their tab key to parentheses. They claim it leads to enlightenment. Such enlightened living forms may find the following program more convenient to type:

exec('%c'*((()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==()))%(((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==()))--((()==())--(()==())),((()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==())),((()==())--(()==())--(()==()))**((()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))--((()==())--(()==())),((()==())--(()==())--(()==())--(()==()))**((()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==()))--((()==())--(()==())--(()==())--(()==())),((()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==())--(()==())--(()==()))**((()==())--(()==()))--((()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==()))**((()==())--(()==()))--((()==())--(()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==()))**((()==())--(()==()))--(()==()),*(((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==()))**((()==())--(()==())--(()==())),)*((()==())--(()==())),((()==())--(()==())--(()==()))**((()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))--((()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==()))--((()==())--(()==())),((()==())--(()==()))**((()==())--(()==())--(()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==()))**((()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==()))--((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==())),((()==())--(()==())--(()==()))**((()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))--((()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==()))--((()==())--(()==())),((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==()))**((()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==()))**((()==())--(()==())),((()==())--(()==())--(()==())--(()==())--(()==())--(()==()))**((()==())--(()==()))--((()==())--(()==())--(()==())),((()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==()))--(()==())))

This program is functionally equivalent to the earlier one. But Python isn't meant for enlightenment. It's meant for getting things done. And to get things done, code should be readable, maintainable, and ideally not resemble an ancient summoning ritual. That's why I personally prefer the earlier style, the one with the ellipses. It gracefully avoids the disconcerting void that lurks within the parentheses. After all, programs must be written for people to read, and only incidentally for machines to execute.

Finally, I must emphasise that you should never deploy code like this in production. If you plan to use something like this for your production CGI scripts, I implore you to add some logging. When dung inevitably collides with the fan, you'll be immensely glad you put some useful logs amidst your business logic. With that little advice, I'll end this brief distraction from reading endless arguments on Internet forums. Happy coding, and may your parentheses stay balanced (and may your ellipses be the punctuation that ...

联系我们 contact @ memedata.com