您的位置:首页 > 编程语言 > Python开发

why python?

2010-07-19 14:20 417 查看
摘自:http://www.linuxjournal.com/article/3882

Apr 30, 2000 By Eric Raymond

in Software

Cardinal Biggles had Eric in the comfy chair for over four hours before
wringing this confession from him...

My first
look at Python was an accident,
and I didn't much like what I saw at the time. It was early 1997,
and Mark Lutz's book Programming Python

from
O'Reilly & Associates had recently come out. O'Reilly books
occasionally land on my doorstep, selected from among the new
releases by some mysterious benefactor inside the organization
using a random process I've given up trying to understand.

One of them was Programming Python

.
I
found this somewhat interesting, as I collect computer languages. I
know over two dozen general-purpose languages, write compilers and
interpreters for fun, and have designed any number of
special-purpose languages and markup formalisms myself. My most
recently completed project, as I write this, is a special-purpose
language called SNG for manipulating PNG (Portable Network
Graphics) images. Interested readers can surf to the SNG home page
at
http://www.catb.org/~esr/sng/
.
I have also written implementations of several odd general-purpose
languages on my Retrocomputing Museum page,
http://www.catb.org/retro/
.

I
had already heard just enough about Python to know that it
is what is nowadays called a “scripting language”, an
interpretive language with its own built-in memory management and
good facilities for calling and cooperating with other programs. So
I dived into Programming Python

with one
question uppermost in my mind: what has this got that Perl does
not?

Perl, of course, is the 800-pound gorilla of modern scripting
languages. It has largely replaced shell as the scripting language
of choice for system administrators, thanks partly to its
comprehensive set of UNIX library and system calls, and partly to
the huge collection of Perl modules built by a very active Perl
community. The language is commonly estimated to be the CGI
language behind about 85% of the “live” content on the Net. Larry
Wall, its creator, is rightly considered one of the most important
leaders in the Open Source community, and often ranks third behind
Linus Torvalds and Richard Stallman in the current pantheon of
hacker demigods.

At that time, I had used Perl for a number of
small projects.
I'd found it quite powerful, even if the syntax and some other
aspects of the language seemed rather ad hoc and prone to bite one
if not used with care. It seemed to me that Python would have quite
a hill to climb as yet another scripting language, so as I read, I
looked first for what seemed to set it apart from Perl.

I
immediately tripped over the first odd feature of Python
that everyone notices: the fact that whitespace (indentation) is
actually significant in the language syntax. The language has no
analog of the C and Perl brace syntax; instead, changes in
indentation delimit statement groups. And, like most hackers on
first realizing this fact, I recoiled in reflexive disgust.

I am
just barely old enough to have programmed in batch
FORTRAN for a few months back in the 1970s. Most hackers aren't
these days, but somehow our culture seems to have retained a pretty
accurate folk memory of how nasty those old-style fixed-field
languages were. Indeed, the term “free format”, used back then to
describe the newer style of token-oriented syntax in Pascal and C,
has almost been forgotten; all

languages have
been designed that way for decades now. Or almost all, anyway. It's
hard to blame anyone, on seeing this Python feature, for initially
reacting as though they had unexpectedly stepped in a steaming pile
of dinosaur dung.

That's certainly how I felt. I skimmed through
the rest of
the language description without much interest. I didn't see much
else to recommend Python, except maybe that the syntax seemed
rather cleaner than Perl's and the facilities for doing basic GUI
elements like buttons and menus looked fairly good.

I put the book
back on the shelf, making a mental note that I
should code some kind of small GUI-centered project in Python
sometime, just to make sure I really understood the language. But I
didn't believe what I'd seen would ever compete effectively with
Perl.

A lot of other things conspired to keep that note way down
on
my priority list for many months. The rest of 1997 was eventful for
me; it was, among other things, the year I wrote and published the
original version of “The Cathedral and the Bazaar”. But I did
find time to write several Perl programs, including two of
significant size and complexity. One of them,
keeper

, is the assistant still
used to file incoming submissions at the Metalab software archive.
It generates the web pages you see at
metalab.unc.edu/pub/Linux/!INDEX.html
.
The other, anthologize

, was used
to automatically generate the PostScript for the sixth edition of
Linux from the Linux Documentation Project's archive of HOWTOs.
Both programs are available at Metalab.

Writing these programs
left me progressively less satisfied
with Perl. Larger project size seemed to magnify some of Perl's
annoyances into serious, continuing problems. The syntax that had
seemed merely eccentric at a hundred lines began to seem like a
nigh-impenetrable hedge of thorns at a thousand. “More than one
way to do it” lent flavor and expressiveness at a small scale, but
made it significantly harder to maintain consistent style across a
wider code base. And many of the features that were later patched
into Perl to address the complexity-control needs of bigger
programs (objects, lexical scoping, “use strict”, etc.) had a
fragile, jerry-rigged feel about them.

These problems combined to
make large volumes of Perl code
seem unreasonably difficult to read and grasp as a whole after only
a few days' absence. Also, I found I was spending more and more
time wrestling with artifacts of the language rather than my
application problems. And, most damning of all, the resulting code
was ugly—this matters. Ugly programs are like ugly suspension
bridges: they're much more liable to collapse than pretty ones,
because the way humans (especially engineer-humans) perceive beauty
is intimately related to our ability to process and understand
complexity. A language that makes it hard to write elegant code
makes it hard to write good code.

With a baseline of two dozen
languages under my belt, I could
detect all the telltale signs of a language design that had been
pushed to the edge of its functional envelope. By mid-1997, I was
thinking “there has to be a better way” and began casting about
for a more elegant scripting language.

One course I did not
consider was going back to C as a
default language. The days when it made sense to do your own memory
management in a new program are long over, outside of a few
specialty areas like kernel hacking, scientific computing and 3-D
graphics—places where you absolutely must get maximum speed and
tight control of memory usage, because you need to push the
hardware as hard as possible.

For most other situations, accepting
the debugging overhead
of buffer overruns, pointer-aliasing problems,
malloc/free

memory leaks and all
the other associated ills is just crazy on today's machines. Far
better to trade a few cycles and a few kilobytes of memory for the
overhead of a scripting language's memory manager and economize on
far more valuable human time. Indeed, the advantages of this
strategy are precisely what has driven the explosive growth of Perl
since the mid-1990s.

I flirted with Tcl, only to discover quickly
that it scales
up even more poorly than Perl. Old LISPer that I am, I also looked
at various current dialects of Lisp and Scheme—but, as is
historically usual for Lisp, lots of clever design was rendered
almost useless by scanty or nonexistent documentation, incomplete
access to POSIX/UNIX facilities, and a small but nevertheless
deeply fragmented user community. Perl's popularity is not an
accident; most of its competitors are either worse than Perl for
large projects or somehow nowhere near as useful as their
theoretically superior designs ought to make them.

My second look
at Python was almost as accidental as my
first. In October 1997, a series of questions on the
fetchmail-friends mailing list made it clear that end users were
having increasing trouble generating configuration files for my
fetchmail

utility. The file uses a
simple, classically UNIX free-format syntax, but can become
forbiddingly complicated when a user has POP3 and IMAP accounts at
multiple sites. As an example, see Listing 1 for a somewhat
simplified version of mine.

Listing
1

I decided to attack the problem by writing an
end-user-friendly configuration editor,
fetchmailconf

. The design
objective of fetchmailconf was clear: to completely hide the
control file syntax behind a fashionable, ergonomically correct GUI
interface replete with selection buttons, slider bars and fill-out
forms.

The thought of implementing this in Perl did not thrill me.
I
had seen GUI code in Perl, and it was a spiky mixture of Perl and
Tcl that looked even uglier than my own pure-Perl code. It was at
this point I remembered the bit I had set more than six months
earlier. This could be an opportunity to get some hands-on
experience with Python.

Of course, this brought me face to face
once again with
Python's pons asinorum

, the
significance of
whitespace. This time, however, I charged ahead and roughed out
some code for a handful of sample GUI elements. Oddly enough,
Python's use of whitespace stopped feeling unnatural after about
twenty minutes. I just indented code, pretty much as I would have
done in a C program anyway, and it worked.

That was my first
surprise. My second came a couple of hours
into the project, when I noticed (allowing for pauses needed to
look up new features in Programming Python

)
I
was generating working

code
nearly as fast as
I could type. When I realized this, I was quite startled. An
important measure of effort in coding is the frequency with which
you write something that doesn't actually match your mental
representation of the problem, and have to backtrack on realizing
that what you just typed won't actually tell the language to do
what you're thinking. An important measure of good language design
is how rapidly the percentage of missteps of this kind falls as you
gain experience with the language.

When you're writing working
code nearly as fast as you can
type and your misstep rate is near zero, it generally means you've
achieved mastery of the language. But that didn't make sense,
because it was still day one and I was regularly pausing to look up
new language and library features!

This was my first clue that, in
Python, I was actually
dealing with an exceptionally good design. Most languages have so
much friction and awkwardness built into their design that you
learn most of their feature set long before your misstep rate drops
anywhere near zero. Python was the first general-purpose language
I'd ever used that reversed this process.

Not that it took me very
long to learn the feature set. I
wrote a working, usable fetchmailconf, with GUI, in six working
days, of which perhaps the equivalent of two days were spent
learning Python itself. This reflects another useful property of
the language: it is compact

--you
can hold its
entire feature set (and at least a concept index of its libraries)
in your head. C is a famously compact language. Perl is notoriously
not; one of the things the notion “There's more than one way to do
it!” costs Perl is the possibility of compactness.

But my most
dramatic moment of discovery lay ahead. My design
had a problem: I could easily generate configuration files from the
user's GUI actions, but editing them was a much harder problem. Or,
rather, reading them into an editable form was a problem.

The
parser for fetchmail's configuration file syntax is
rather elaborate. It's actually written in YACC and Lex, two
classic UNIX tools for generating language-parsing code in C. In
order for fetchmailconf to be able to edit existing configuration
files, I thought it would have to replicate that elaborate parser
in Python. I was very reluctant to do this, partly because of the
amount of work involved and partly because I wasn't sure how to
ascertain that two parsers in two different languages accept the
same. The last thing I needed was the extra labor of keeping the
two parsers in synchronization as the configuration language
evolved!

This problem stumped me for a while. Then I had an
inspiration: I'd let fetchmailconf use fetchmail's own parser! I
added a --configdump
option to fetchmail that
would parse .fetchmailrc and dump the result to standard output in
the format of a Python initializer. For the file above, the result
would look roughly like Listing 2 (to save space, some data not
relevant to the example is omitted).

Listing
2

Python could then evaluate the fetchmail
--configdump
output and have the configuration
available as the value of the variable “fetchmail”.

This wasn't
quite the last step in the dance. What I really
wanted wasn't just for fetchmailconf to have the existing
configuration, but to turn it into a linked tree of live objects.
There would be three kinds of objects in this tree:
Configuration

(the top-level
object representing the entire configuration),
Site

(representing one of the
sites to be polled) and User

(representing user data attached to a site). The example file
describes five site objects, each with one user object attached to
it.

I had already designed and written the three object classes
(that's what took four days, most of it spent getting the layout of
the widgets just right). Each had a method that caused it to pop up
a GUI edit panel to modify its instance data. My last remaining
problem was somehow to transform the dead data in this Python
initializer into live objects.

I considered writing code that
would explicitly know about
the structure of all three classes and use that knowledge to grovel
through the initializer creating matching objects, but rejected
that idea because new class members were likely to be added over
time as the configuration language grew new features. If I wrote
the object-creation code in the obvious way, it would be fragile
and tend to fall out of sync when either the class definitions or
the initializer structure changed.

What I really wanted was code
that would analyze the shape
and members of the initializer, query the class definitions
themselves about their members, and then adjust itself to
impedance-match the two sets.

This kind of thing is called metaclass
hacking

and is generally considered fearsomely
esoteric—deep black magic. Most object-oriented languages don't
support it at all; in those that do (Perl being one), it tends to
be a complicated and fragile undertaking. I had been impressed by
Python's low coefficient of friction so far, but here was a
real

test. How hard would I have
to wrestle
with the language to get it to do this? I knew from previous
experience that the bout was likely to be painful, even assuming I
won, but I dived into the book and read up on Python's metaclass
facilities. The resulting function is shown in Listing 3, and the
code that calls it is in Listing 4.

Listing
3

Listing
4

That doesn't look too bad for deep black magic, does it?
Thirty-two lines, counting comments. Just from knowing what I've
said about the class structure, the calling code is even readable.
But the size of this code isn't the real shocker. Brace yourself:
this code only took me about ninety minutes to write—and it worked
correctly the first time I ran it

.

To
say I was astonished would have been positively wallowing
in understatement. It's remarkable enough when implementations of
simple

techniques work exactly as
expected the
first time; but my first metaclass hack in a new language, six days
from a cold standing start? Even if we stipulate that I am a fairly
talented hacker, this is an amazing testament to Python's clarity
and elegance of design.

There was simply no way I could have
pulled off a coup like
this in Perl, even with my vastly greater experience level in that
language. It was at this point I realized I was probably leaving
Perl behind.

This was my most dramatic Python moment. But, when
all is
said and done, it was just a clever hack. The long-term usefulness
of a language comes not in its ability to support clever hacks, but
from how well and how unobtrusively it supports the day-to-day work
of programming. The day-to-day work of programming consists not of
writing new programs, but mostly reading and modifying existing
ones.

So the real

punchline
of the story is
this: weeks and months after writing fetchmailconf, I could still
read the fetchmailconf code and grok what it was doing without
serious mental effort. And the true reason I no longer write Perl
for anything but tiny projects is that was never true when I was
writing large masses of Perl code. I fear the prospect of ever
having to modify keeper or anthologize again—but fetchmailconf
gives me no qualms at all.

Perl still has its uses. For tiny
projects (100 lines or
fewer) that involve a lot of text pattern matching, I am still more
likely to tinker up a Perl-regexp-based solution than to reach for
Python. For good recent examples of such things, see the
timeseries

and
growthplot

scripts in the
fetchmail distribution. Actually, these are much like the things
Perl did in its original role as a sort of combination
awk/sed/grep/sh, before it had functions and direct access to the
operating system API. For anything larger or more complex, I have
come to prefer the subtle virtues of Python—and I think you will,
too.

Resources

All
listings referred to in this article are available by
anonymous download in the file
ftp.linuxjournal.com/pub/lj/listings/issue73/3882.tgz
.



Eric Raymond

is a Linux advocate and
the author of The Cathedral & The
Bazaar

. He can be
reached via e-mail at (esr@thyrsus.com
).

中文版

摘自:http://blog.csdn.net/yzx714/archive/2009/07/17/4357511.aspx

想必大家都知道一种新型的解释性语言叫python,它轻巧,实用,可移植,极大的减低了程序员的工作的复杂性

著名的程序员Bruce Eckel在他的著作——Thinking In
Java的第二版中说:python语言最接近征服程序开发与维护的种种复杂度的目标(但是Bruce Eckel在Thinking In
Java第三版中因为种种原因收回了这句话,但是这不能抹去大师对python的喜爱)

另一个与python有关的大师当然是ESR,ESR是我最崇敬的黑客,我认为ESR可以说是开源世界中第二有号召力的人(第一位当然是
Linus),ESR在很多地方都表示python语言是他的最爱,并且在他的著作《HOW TO BE A
HACKER》中把python列为黑客必需掌握的5种语言,并且是一名黑客应该最先学习的语言

说到这里,ESR还有一篇文章——why
python,详细的介绍了他认识python的过程,从不屑一顾到爱不释手,文中把python同其他语言进行了对比(包括
perl,lisp,c/c++)文章是学习python了解python的瑰宝

遗憾的是,Why
python只有一个英文版本和一个翻译得感觉不那么好的中文版本(翻译人是chaox,我没有贬低他劳动成果的意思,我感谢他对黑客文化做的贡献)所以
我翻译了一个比较好的版本

(翻译人是我(JY)以及Anderson997,shiningocean也帮忙查对)

CSDN上看字体比较难看,并且会遗漏很多信息,所以我特地上传了PDF版和DOC版,在我的纳米盘里,英文原版也可以在那里找到

PDF版下载:http://d.namipan.com/d/whypython.pdf/0b540c5c53d8a98bdb27678a0934100cb92dd17b36f60600

DOC
版下载:

http://www.namipan.com/d/whypython%e6%ad%a3%e5%bc%8f.doc/004609035aaeaa8eb7336ed368bd8bd0d03859a300800000

html下载:

http://www.namipan.com/d/whypython.html/78dbca685a31dba734c5de5758d781a17696ea7c74d60100

原版英文(doc)下载:

http://www.namipan.com/d/why%20python%20E.doc/60ea14fd465141f882c14900e3e3b5b29350757b00cc0000

Why python

Eric Raymond

翻译:JY-YZX714

&
ANDERSON997

第一次看到python
纯属偶然,而且那时我还并不喜欢它。
1997
年初,

O’Reilly & Associates
推出

Mark Lutz


书Programming Python

O’Reilly
公司赠送的
书有时会被放在我家的门前,
这些书是
从一堆新书中
随机
选出来的,我从来不去考虑他
们怎么来选书。

其中一本就是
Programming Python


发现它还有点意思,
因为我

搜集计算机语言
的爱好

目前我已了解
二十

种通用语言,出于兴趣我还写
了些编译器,设计

几种特用语言并且制定它们
的标准。当我写这篇文章时,我最近完成的项目是一个叫SNG
的特用语言,它用来处理
PNG
图像,有兴趣的读者可以
浏览
SNG
的主页(
http://www.catb.org /~esr/sng/

)我也

了几个特殊的通用语言,你可
以找到他们在我的“
古董机博物馆

的网页。(
http://www.catb.org/retro/


关于python


我已经听说过很多,知道它是一种“
脚本语言

,或者一种解释性语言,它有


自己的内存管理器以及很好的
调用或协调其他程序的能力。所以

带着“

什么

python比
perl


好”
或者

python
具有哪些
perl
所没有的东西”
的问题

我钻进了
Programming Python
这本书。

众所周知,
Perl
是现代
脚本语言
的王者
,对于系统管理员来说,它

很大程度上替代了shell
。这当然归功于广泛的
UNIX
库以及系统接口,


归功于活跃的Perl
社区所提供的数不胜数的模块。据估计,目前网上
85%


“有效”
内容是由它做后台CGI
语言的。它的作者

Larry Wall
理所当然
成为开源社区最重要的领导人之一,其在黑客中的声望仅次于Linus Torvalds(
译注:LINUX
系统的作者

)

Richard Stallman(

译注:
GUN的发起者)



那时,我用perl
来编写了一些小项目


即使
在使用中
一不小心

在语法和其他方面出

错,
而且它还有些过于专门化,
我仍然认为
perl
威力强大

我认为python
就像其他脚本语言一样

,仅是
小山
而已,
容易翻越

所以学它的时候,只是
想看看它跟
perl
有什么不同而已


跟许多人一样,

马上就绊倒在
python的一个奇怪特性


:空格(缩进)在

语言中有太重要的意义,它不像C

Perl
那样用一对大括号
{}
来划分区块,取而代之的是
用缩进来划分语句块。于是,和

大多数
黑客一
样,缘
于反射性的厌恶,
我马上就放弃了它 。

上世纪70
年代,我

还太小,没有赶上
用FORTRAN
编程

的“乐趣”,其实,今天
大多数黑客

没有
这样的
经历,但是
不知为何,
黑客文化
却把这种
对强制缩进的厌恶清晰地保留

下来。事实上,所谓的
“自由格式”,那个
在C

pascal

用来描述一种新的
token-oriented syntax
的词汇,都已经被人遗忘了。几十年以来,所有的语言,
或者说基本上所有语言都
是用该语言
设计
的。这就不难
理解大多数人在看到python
的强制缩进格式的时候

那种
像踩到狗屎的表情。

那也是我的感觉,我失去了对python
的兴趣,飞快的浏览了一下对
python
的余下介绍

。我没有发现多少值得推荐的地方,仅是句法比perl

更清晰
,用于基本的
GUI
成分的工具箱,如按钮、菜单什么的也非常不错。

我把书放回了书架,心想
自己哪天应该
用python
来写一些规模较小,
GUI
为主的项目来


确保
自己确实掌握了
这门语言,但我还是不相信我
所看到的python
能与
perl
抗衡。

后来的几个月里,
琐事庞杂,这个想法始终没有排上议事日程。
1997对我意义重大,那年,我撰写并出版了《大教堂与市集》的第一版,但是我仍然抽出时间去写了几个
perl
程序,其中包括两个比较大型的项目,其中一个是


keeper
”,它用于
Metalab
软件中导入文件,可以在 http://metalab.unc.edu/pub/Linux/!INDEX.html 里找到它;另一个是


anthologize


用来从LINUX
文档的
HOWTOs


自动生成第六版LINUX
系统的
PostScript
,这两个程序都

运用在
Metalab



写这些程序让我开始对perl
不满,


大型项目
中,
perl的

那些
小毛病
被放大,
变得特别严重
,而且连续不断


一百行代码
里,这些
语法格式
仅是有些
让人迷惑,而

一千行代码
里,那就几近是不可逾越的荆棘了。
perl “凡事无绝对

的特性在小规模项目中表现良好,而在大规
模项目中这个特性就使程序难以保持统一风格和稳固的基础。

更有甚者

那些为了满足大型程序复杂性控制需要而加入的补丁多有脆弱、偷工减料的毛病。


些问题
混在一起,
使得

perl代码编写

的大型程序
几天
不接触
就难以阅读,
难以把它当做一个整体来掌握。
另外,我发现我大多数时间
不是在解决我的应用程序的问题,而是在解决perl
语言本身的问题。更令人头疼的是
——

生成的
代码
非常
丑陋!
这是有影响的!
丑陋的程序就像丑陋的桥梁,
丑陋的总比漂亮的
更容易
坍塌
,因为人类(特别是工程师)
觉知
美感
的方式

其加工复杂事物
的能力息息相关

如果一门语言写不出漂亮的代
码那就
难以
写出优秀的代码。


二十多种语言
作为
基础,我能
敏锐觉察
一门语言
所能达到功能的所有迹象。

一直到
1997年


,我

在思索
这样一个问题:
“是不是有一个更好的方法


”并且开始去
寻找一个更好的脚本语言


不会考虑把C
语言作为默认语言

。除了几个
特殊的领域
外,
像内核技术,科学计算以及三
维图像处理
等,在新程序
中需要
自己完成内存管理的日子已经远去。只有在这些领域才
要求严格的内存控制,极高的速度,因


也需要
让你的硬件尽可能的发挥它的
潜力!


有其他的情况,
诸如
接受缓冲区溢出的调试,指
针的指向问题,
malloc/free

译注:
这是C
语言中申请释放内存的函数)

导致的内存泄露和其他一些问
题仍在现在的机器上撒野,所以在内存管理器上有一点开销是非常值得的,那样可以节约更多的人力和时间,事实上,正是这个理念
促使了
perl飞速的发展。


尝试Tc1
,却发现它比
perl

好像更糟糕。像我这样的
老资格lisp
程序员,也看到了各种各样的
lisp
的方言和

方案
,但lisp
的一贯作风就是缺少或者根本没有文档、不能
完全兼容
POSIX/UNIX
机器,

用户社区规模小且零碎,所以提出的许多有创见的设计基本是无用的。因而perl
的流行并非偶然,它的大多数竞争者要么是在大项目上表现得比
perl
差,要么就是不像它们所提出的理论那样好。


第二次
关注
python和第一次一样完全

出于
偶然

1997年的
10
月,
fetchmail


译注:
这是ESR
的写的一个邮件系统,在
ESR
的《大教堂与市集》中有
比较详细的开发经过)

邮件列表
所反映的
系列问题说明许多用户
因为我的
fechmail
公用程序在生成
配置文件
时遇到了麻烦
。这个文件本身使用简单的但
是经典的UINIX free-format
格式,但是有可能




用户拥有POP3

IMAP
账号时变得异常复杂

。来
看这个例子,Listing 1
,这是我的一个简化版本。

Listing 1


编写一个叫做fetchmailconf
的贴近终端用户的配置编辑器来解决这个问题


这个设计的目的很明确,
就是要
将控制文件
完全
隐藏在一个时尚的,符合
人机功效学
的GUI

界面
后面,
该界面
应该有选择按钮,滚动条和编
辑框。

以perl
来完成的念头很快被打消,我见过
perl

GUI
代码,只是
perl

Tc1
的一个混合而已,那看起来比我的纯
perl
代码还要丑陋

。就在这时,
我想起了六个月前的那个小心愿,这也许是着手实践python
的一个好机会。

当然,这得让我再次直面python
为人所不齿的强制缩进,但这次我选择了坚持,随便写了些
GUI
的代码。可真够奇怪的,对
python
的强制缩进的不爽
感觉竟然在
20
分钟之后消失了,我只是缩进代码,就想我在
C
里面做的一样。

那是我得到的第一个惊
喜,下一个在几个小时后接踵而来,我发现到
我编写代码的速度
几乎和我
打字的速度
一样快
。当我意识到这点时,我非常吃惊。衡量编程
费力程度的
重要
标准是
看出现这

情况
的频率
:你写出的代码

你心
里对
问题
的表征不匹配
,你不得不
回溯已写的代码,发现刚
输入的代码
并没有让语言执行你想的事情
。衡量
一个
语言
设计优劣的重要
标准就是你从这门语言中获得
经验的过程中多
久又
“失足

于这类

错误



你写代码的速度和你打字的速度一样快并且失误率为0



那就意味着


充分理解了这门语言
。这仍没有什么大不了的

不过第一天而已
,我还会经常停下来查阅新语
言。


正在和一门异常优秀的语言打交道
,这
是我在python
中得到的第一个
线索。
大多数语言有许多尴尬的设计被添加进其中,以至于你在失误率为0
之前的很


一段时间你都必须学习他们大多数的库。Python
是我第一个用

的打破这个规律的语言。


并没有花很多时间来学习它的库,我花6
天写出了一个可工作的、实用的有
GUI

fetchmail
配置编辑器,并且其中还有两天被
用来学习
python
本身。这反映出
python
的另一个有用的特
点:它





,以至
你可以把整个库记下来(至
少是库的概念索引)。C
是一门著名的高效语言,
perl
却恰恰是另一个极端。

凡事无绝对


perl
很难高效。


过,我印象

深刻的发现还在后面。我的
设计有个问题:我可以很容易
地从
用户界面来生成
配置文件,但却很难对它们进行
编辑

或者说,把配置文件读入
可编辑的模式出现了
问题。

Fetchmail
配置文件的解析器非常好,是用YACC

LEX
写的,那是
C
语言中两个经典的用来生成

编译器代码的
UNIX工具。为了

fetchmail
配置编辑器能够编辑已有配置文件,我想可能要用
python
重写那样一个解析器。我不想那样做,一是因为太大的工作量,二是因为我尚不清楚怎样让两种不同语
言编写的解析器接受同样的东西。另外,我还需要额外的工作以来让两种解析器同步,这可是配置语言所必须的。

这个问题让我愣了一会
儿,然后我突然有了灵感:我可以让fetchmail
配置编辑器使用
fetchmail
自己的解析
器,再为
fetchmail
增加一个配置转储的选项来解析。把
Fetchmail
的资源文件和导出的结果放到
python
加载器的标准输
出里!


面的文件你可以在listing2
中看到。(简洁起见,与本例无关的内容已被删除。)

Listing 2


样python
就可以评估
fetchmail


配置转储
输出
,而且使配置变成可用的
``fetchmail''.
变量。

这还不是
我的最终目的。
我真正想要的并不仅仅是让fetchmailconf
拥有已经存在的配置,而是要它

把把所有
动态对象链接起来
形成一个
树型结构

这种树型结构中有三种
类型
,分别是:配置(代表了整个
配置的最顶层的对象),


(代
表其中一个
被考察的网)
以及用户(代表一个站点上
存放的用户数据)。案例文件中描述了五个
站点
对象,每一个都被加入了一个用户对象。


已经设计并写下了这三个类(用时四天,其中大部分时间用在了调整窗口组件的布局)。每个类都有一个办法可以弹出一个图形化界面的编辑面板来修改其自身的数
据。最后剩下的问题就是如何将python
的初始化程序中无用的数据转化为

动态
的对象。


曾考虑写些可以明确知道这三类结构
的代码,而且可以
利用这
些知识

检索
初始化程序创建对应的对象
的过程,
但又放弃了这一想法,因为新
的类成员会随着时间的流逝而加入

就像配置语言发展出新特性一样。如果我以这种明显的方式来编写这一创建对象的代码,那当类定义或是初始化程序结构发生改变时,代码就
将变得十分脆弱而且也容易难以同步更新。


真正想要


这样的代码,它
能够
自行
分析初始化程序的
轮廓
和成员,能够查询自身类成员
的定义并且将其自身调整到相匹配的2


容器
里去



种事就是被称为元类,通常也被认为是令人望而生畏而又神秘的
黑魔法
。大多数面向对象语言根本并不支持这一特性;在那些能这样做的语言中(perl
就是其中之一),这又会是一个复杂而又脆弱的计划。就某种程度上说我被
python

很低的
冲突率而打动,但真正的测试
才刚开始。我要用python
去完成这一目标究竟会有多困难?以我从前的经历来看,这一仗将会很艰苦。即使我

真会
赢,我也是靠把关于python
的元类的资料翻个底朝天。结果函数在
listing3

(译者注:我们是在ESR
的网站上找到的英文原版,但原版中并没有这部分,可能是被
ESR
删去了)

中会被呈现,实现的代码则在listing4
中。

Listing3

Listing4


来对
黑魔法
来说还不算太糟,不是吗?32
行代码,还包括注释。

仅从我刚讲的所谓
类的结构
就知道
,调用的代码也很
具可读性
。但这样的代码量还不是真正
令人震撼的。振作起来:我只花了大约90
分钟就写就了这些代码,而且第一次就正确运行。


得不承认在不知不觉中我确实变得沉溺于此。而仅仅是一些小小的技巧就能达到当初所期望的目的,也的确是令人难以忘怀的。但我从零开始,仅用时六天就
创造
了一门新语言的一个元类?即
使说我是一个天生的
黑客
,这也从事实上证明了pyhon
在设计上的清晰和高雅




使我对于perl
的掌握已经到达了很高的境界,但是我仍然无法想象用
perl
能够实现这样一个颠覆性的转变。到此时我才意识到或许我应该把
Perl
抛诸脑后。


是我激动人心的python
时刻。但是,所有说过的和做过的,也只不过是一次取巧的

黑客创造
而已。一门语言之所以长期有
用,并不是因为


支持某个
取巧的
黑客创造
,而是取决于
它能在多大程度上为
日常编程工作
提供
支持。日常编程工作并不

是编写新程序,而更多的是对
已有程序的阅读以及修改。


以,故事的重点在于:当花费了大量的时间编写fetchmail

的配置编辑器
,我仍能毫不费力的读懂并

会这些代码的作用。我之所以
不再用perl
写任何程序,小项目除外,真正原因就在于我从没感觉到
perl
写就的大段代码能让我感到满意。我实在不想再去做任何修改或者编选的工作

——
但是fetchmailconf
从来就没有



收到如此的折腾



然perl
仍然有其用处。对于代码少于
100
行同时又涉及大量的文
本匹配的小项目来说,我仍然偏向于通过修补基于
perl
的方案来达成目的,而不是通过
python



于新的类似的有代表性的例子,可以参看fetchmail
发行版的

发行日志
和的脚本。事实上,这些很像Perl
在拥有函数和直接接
入操作系统的
API
之前,也就是作为
awk/sed/grep/sh

一个混合体


扮演的
原始作用相似
。而对于任何更大更复杂的项目,我更倾向于使用有精细等诸多优点的python
,而我相信你也会
这样做的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: