<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>汇集博客 &#187; 编程其他</title>
	<atom:link href="http://www.zhblog.net/archives/category/%e7%bc%96%e7%a8%8b%e5%85%b6%e4%bb%96/feed" rel="self" type="application/rss+xml" />
	<link>http://www.zhblog.net</link>
	<description>专注网站建设，博客优化，转载别人，写出自己</description>
	<lastBuildDate>Mon, 09 Jan 2012 02:16:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Javascript 面向对象编程</title>
		<link>http://www.zhblog.net/archives/955.html</link>
		<comments>http://www.zhblog.net/archives/955.html#comments</comments>
		<pubDate>Mon, 09 Jan 2012 02:16:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[编程其他]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.zhblog.net/?p=955</guid>
		<description><![CDATA[Javascript是一个类C的语言，他的面向对象的东西相对于C++/Java比较奇怪，但是其的确相当的强大，在 Todd 同学的“对象的消息模型”一文中我们已经可以看到一些端倪了。这两天有个前同事总在问我Javascript面向对象的东西，所以，索性写篇文章让他看去吧，这里这篇文章主要想从一个整体的解度来说明一下Javascript的面向对象的编程。（成文比较仓促，应该有不准确或是有误的地方，请大家批评指正） 初探 我们知道Javascript中的变量定义基本如下： var name = 'Chen Hao';; var email = 'haoel(@)hotmail.com'; var website = 'http://coolshell.cn'; 如果要用对象来写的话，就是下面这个样子： var chenhao = { name :'Chen Hao', email : 'haoel(@)hotmail.com', website : 'http://coolshell.cn' }; 于是，我就可以这样访问： //以成员的方式 chenhao.name; chenhao.email; chenhao.website; //以hash map的方式 chenhao["name"]; chenhao["email"]; chenhao["website"]; 关于函数，我们知道Javascript的函数是这样的： &#160; var doSomething = function(){ alert('Hello World.'); }; 于是，我们可以这么干： var sayHello [...]]]></description>
			<content:encoded><![CDATA[<p>Javascript是一个类C的语言，他的面向对象的东西相对于C++/Java比较奇怪，但是其的确相当的强大，在 <a onclick="pageTracker._trackPageview('/outgoing/www.cnblogs.com/weidagang2046/?referer=http%3A%2F%2Fweibo.com%2Fzzlau%3Fwvr%3D4%26lf%3Dreg%26page%3D3%26pre_page%3D2%26end_id%3D3399859468127472');" href="http://www.cnblogs.com/weidagang2046/" target="_blank">Todd 同学</a>的“<a title="对象的消息模型" href="http://coolshell.cn/articles/5202.html" rel="bookmark" target="_blank">对象的消息模型</a>”一文中我们已经可以看到一些端倪了。这两天有个前同事总在问我Javascript面向对象的东西，所以，索性写篇文章让他看去吧，这里这篇文章主要想从一个整体的解度来说明一下Javascript的面向对象的编程。（<strong>成文比较仓促，应该有不准确或是有误的地方，请大家批评指正</strong>）</p>
<h4>初探</h4>
<p>我们知道Javascript中的变量定义基本如下：</p>
<pre class="brush: jscript; title: ; notranslate" title="">var name = 'Chen Hao';;
var email = 'haoel(@)hotmail.com';
var website = 'http://coolshell.cn';</pre>
<p>如果要用对象来写的话，就是下面这个样子：</p>
<pre class="brush: jscript; title: ; notranslate" title="">var chenhao = {
    name :'Chen Hao',
    email : 'haoel(@)hotmail.com',
    website : 'http://coolshell.cn'
};</pre>
<p>于是，我就可以这样访问：</p>
<pre class="brush: jscript; title: ; notranslate" title="">//以成员的方式
chenhao.name;
chenhao.email;
chenhao.website;

//以hash map的方式
chenhao["name"];
chenhao["email"];
chenhao["website"];</pre>
<p>关于函数，我们知道Javascript的函数是这样的：</p>
<p>&nbsp;</p>
<pre class="brush: jscript; title: ; notranslate" title="">var doSomething = function(){
   alert('Hello World.');
};</pre>
<p>于是，我们可以这么干：</p>
<pre class="brush: jscript; title: ; notranslate" title="">var sayHello = function(){
   var hello = "Hello, I'm "+ this.name
                + ", my email is: " + this.email
                + ", my website is: " + this.website;
   alert(hello);
};

//直接赋值，这里很像C/C++的函数指针
chenhao.Hello = sayHello;

chenhao.Hello();</pre>
<p>相信这些东西都比较简单，大家都明白了。 可以看到javascript对象函数是直接声明，直接赋值，直接就用了。runtime的动态语言。<span id="more-955"></span></p>
<p>还有一种比如规范的写法是：</p>
<pre class="brush: jscript; title: ; notranslate" title="">//我们可以看到， 其用function来做class。
var Person = function(name, email, website){
    this.name = name;
    this.email = email;
    this.website = website;

    this.sayHello = function(){
        var hello = "Hello, I'm "+ this.name  + ", \n" +
                    "my email is: " + this.email + ", \n" +
                    "my website is: " + this.website;
        alert(hello);
    };
};

var chenhao = new Person("Chen Hao", "haoel@hotmail.com",
                                     "http://coolshell.cn");
chenhao.sayHello();</pre>
<p>顺便说一下，要删除对象的属性，很简单：</p>
<pre class="brush: jscript; title: ; notranslate" title="">delete chenhao['email']</pre>
<p>上面的这些例子，我们可以看到这样几点：</p>
<p>Javascript的数据和成员封装很简单。</p>
<p><a href="http://www.zhblog.net/archives/tag/javascript" class="st_tag internal_tag" rel="tag" title="标签 javascript 下的日志">Javascript</a> function中的this指针很关键，如果没有的话，那就是局部变量或局部函数。</p>
<p>Javascript对象成员函数可以在使用时临时声明，并把一个全局函数直接赋过去就好了。</p>
<p>Javascript的成员函数可以在实例上进行修改，也就是说不同的实例的同一个函数名的行为和实现不一样。</p>
<h4>属性配置 – Object.defineProperty</h4>
<p>先看下面的代码：</p>
<pre class="brush: jscript; title: ; notranslate" title="">//创建对象
var chenhao = Object.create(null);

//设置一个属性
 Object.defineProperty( chenhao,
                'name', { value:  'Chen Hao',
                          writable:     true,
                          configurable: true,
                          enumerable:   true });

//设置多个属性
Object.defineProperties( chenhao,
    {
        'email'  : { value:  'haoel@hotmail.com',
                     writable:     true,
                     configurable: true,
                     enumerable:   true },
        'website': { value: 'http://coolshell.cn',
                     writable:     true,
                     configurable: true,
                     enumerable:   true }
    }
);</pre>
<p>下面就说说这些属性配置是什么意思。</p>
<ul>
<li>writable：这个属性的值是否可以改。</li>
<li>configurable：这个属性的配置是否可以改。</li>
<li>enumerable：这个属性是否能在for…in循环中遍历出来或在Object.keys中列举出来。</li>
<li>value：属性值。</li>
<li>get()/set(_value)：get和set访问器。</li>
</ul>
<h4>Get/Set 选择器</h4>
<p>关于get/set访问器，它的意思就是用get/set来取代value（其不能和value一起使用），示例如下：</p>
<pre class="brush: jscript; title: ; notranslate" title="">var  age = 0;
Object.defineProperty( chenhao,
            'age', {
                      get: function() {return age+1;},
                      set: function(value) {age = value;}
                      enumerable : true,
                      configurable : true
                    }
);
chenhao.age = 100; //调用set
alert(chenhao.age); //调用get 输出101;</pre>
<p>我们再看一个更为实用的例子——利用已有的属性(age)通过get和set构造新的属性(birth_year)：</p>
<pre class="brush: jscript; title: ; notranslate" title="">Object.defineProperty( chenhao,
            'birth_year',
            {
                get: function() {
                    var d = new Date();
                    var y = d.getFullYear();
                    return ( y - this.age );
                },
                set: function(year) {
                    var d = new Date();
                    var y = d.getFullYear();
                    this.age = y - year;
                }
            }
);

alert(chenhao.birth_year);
chenhao.birth_year = 2000;
alert(chenhao.age);</pre>
<p>这样做好像有点麻烦，你说，我为什么不写成下面这个样子：</p>
<pre class="brush: jscript; title: ; notranslate" title="">var chenhao = {
    name: "Chen Hao",
    email: "haoel@hotmail.com",
    website: "http://coolshell.cn",
    age: 100,
    get birth_year() {
        var d = new Date();
        var y = d.getFullYear();
        return ( y - this.age );
    },
    set birth_year(year) {
        var d = new Date();
        var y = d.getFullYear();
        this.age = y - year;
    }

};
alert(chenhao.birth_year);
chenhao.birth_year = 2000;
alert(chenhao.age);</pre>
<p>是的，你的确可以这样的，不过通过defineProperty()你可以干这些事：</p>
<p>1）设置如 writable，configurable，enumerable 等这类的属性配置。</p>
<p>2）动态地为一个对象加属性？比如：一些HTML的DOM对像。</p>
<h4>查看对象属性配置</h4>
<p>如果查看并管理对象的这些配置，下面有个程序可以输入这些东西：</p>
<pre class="brush: jscript; title: ; notranslate" title="">//列出对象的属性.
function listProperties(obj)
{
    var newLine = "&lt;br /&gt;";
    var names = Object.getOwnPropertyNames(obj);
    for (var i = 0; i &lt; names.length; i++) {
        var prop = names[i];
        document.write(prop + newLine);

        // 列出对象的属性配置（descriptor）动用getOwnPropertyDescriptor函数。
        var descriptor = Object.getOwnPropertyDescriptor(obj, prop);
        for (var attr in descriptor) {
            document.write("..." + attr + ': ' + descriptor[attr]);
            document.write(newLine);
        }
        document.write(newLine);
    }
}

listProperties(chenhao);</pre>
<h4>call，apply， bind 和 this</h4>
<p>关于Javascript的this指针，和C++/Java很类似。 我们来看个示例：（这个示例很简单了，我就不多说了）</p>
<pre class="brush: jscript; title: ; notranslate" title="">function print(text){
    document.write(this.value + ' - ' + text+ '&lt;br&gt;');
}

var a = {value: 10, print : print};
var b = {value: 20, print : print};

print('hello');// this =&gt; global, output "undefined - hello"

a.print('a');// this =&gt; a, output "10 - a"
b.print('b'); // this =&gt; b, output "20 - b"

a['print']('a'); // this =&gt; a, output "10 - a"</pre>
<p>我们再来看看call 和 apply，这两个函数的差别就是参数的样子不一样，另一个就是性能不一样，apply的性能要差很多。（关于性能，可到 <a onclick="pageTracker._trackPageview('/outgoing/jsperf.com/?referer=http%3A%2F%2Fweibo.com%2Fzzlau%3Fwvr%3D4%26lf%3Dreg%26page%3D3%26pre_page%3D2%26end_id%3D3399859468127472');" href="http://jsperf.com/" target="_blank">JSPerf</a> 上去跑跑看看）</p>
<pre class="brush: jscript; title: ; notranslate" title="">print.call(a, 'a'); // this =&gt; a, output "10 - a"
print.call(b, 'b'); // this =&gt; b, output "20 - b"

print.apply(a, ['a']); // this =&gt; a, output "10 - a"
print.apply(b, ['b']); // this =&gt; b, output "20 - b"</pre>
<p>但是在bind后，this指针，可能会有不一样，但是因为Javascript是动态的。如下面的示例</p>
<pre class="brush: jscript; title: ; notranslate" title="">var p = print.bind(a);
p('a');             // this =&gt; a, output "10 - a"
p.call(b, 'b');     // this =&gt; a, output "10 - a"
p.apply(b, ['b']);  // this =&gt; a, output "10 - a"</pre>
<h4>继承 和 重载</h4>
<p>通过上面的那些示例，我们可以通过Object.create()来实际继承，请看下面的代码，Student继承于Object。</p>
<pre class="brush: jscript; title: ; notranslate" title="">var Person = Object.create(null);

Object.defineProperties
(
    Person,
    {
        'name'  : {  value: 'Chen Hao'},
        'email'  : { value : 'haoel@hotmail.com'},
        'website': { value: 'http://coolshell.cn'}
    }
);

Person.sayHello = function (person) {
    var hello = "&lt;p&gt;Hello, I am "+ this.name  + ", &lt;br&gt;" +
                "my email is: " + this.email + ", &lt;br&gt;" +
                "my website is: " + this.website;
    document.write(hello + "&lt;br&gt;");
}

var Student = Object.create(Person);
Student.no = "1234567"; //学号
Student.dept = "Computer Science"; //系

//检查Person的属性
document.write(Student.name + ' ' + Student.email + ' ' + Student.website +'&lt;br&gt;');

//检查Person的方法
Student.sayHello();

//重载SayHello方法
Student.sayHello = function (person) {
    var hello = "&lt;p&gt;Hello, I am "+ this.name  + ", &lt;br&gt;" +
                "my email is: " + this.email + ", &lt;br&gt;" +
                "my website is: " + this.website + ", &lt;br&gt;" +
                "my student no is: " + this. no + ", &lt;br&gt;" +
                "my departent is: " + this. dept;
    document.write(hello + '&lt;br&gt;');
}
//再次调用
Student.sayHello();

//查看Student的属性（只有 no 、 dept 和 重载了的sayHello）
document.write('&lt;p&gt;' + Object.keys(Student) + '&lt;br&gt;');</pre>
<p>通用上面这个示例，我们可以看到，Person里的属性并没有被真正复制到了Student中来，但是我们可以去存取。这是因为Javascript用委托实现了这一机制。其实，这就是Prototype，Person是Student的Prototype。</p>
<p>当我们的代码需要一个属性的时候，Javascript的引擎会先看当前的这个对象中是否有这个属性，如果没有的话，就会查找他的Prototype对象是否有这个属性，一直继续下去，直到找到或是直到没有Prototype对象。</p>
<p>为了证明这个事，我们可以使用Object.getPrototypeOf()来检验一下：</p>
<pre class="brush: jscript; title: ; notranslate" title="">Student.name = 'aaa';

//输出 aaa
document.write('&lt;p&gt;' + Student.name + '&lt;/p&gt;');

//输出 Chen Hao
document.write('&lt;p&gt;' +Object.getPrototypeOf(Student).name + '&lt;/p&gt;');</pre>
<p>于是，你还可以在子对象的函数里调用父对象的函数，就好像C++里的 Base::func() 一样。于是，我们重载hello的方法就可以使用父类的代码了，如下所示：</p>
<pre class="brush: jscript; title: ; notranslate" title="">//新版的重载SayHello方法
Student.sayHello = function (person) {
    Object.getPrototypeOf(this).sayHello.call(this);
    var hello = "my student no is: " + this. no + ", &lt;br&gt;" +
                "my departent is: " + this. dept;
    document.write(hello + '&lt;br&gt;');
}</pre>
<p>这个很强大吧。</p>
<h4>组合</h4>
<p>上面的那个东西还不能满足我们的要求，我们可能希望这些对象能真正的组合起来。为什么要组合？因为我们都知道是这是OO设计的最重要的东西。不过，这对于Javascript来并没有支持得特别好，不好我们依然可以搞定个事。</p>
<p>首先，我们需要定义一个Composition的函数：（target是作用于是对象，source是源对象），下面这个代码还是很简单的，就是把source里的属性一个一个拿出来然后定义到target中。</p>
<pre class="brush: jscript; title: ; notranslate" title="">function Composition(target, source)
{
    var desc  = Object.getOwnPropertyDescriptor;
    var prop  = Object.getOwnPropertyNames;
    var def_prop = Object.defineProperty;

    prop(source).forEach(
        function(key) {
            def_prop(target, key, desc(source, key))
        }
    )
    return target;
}</pre>
<p>有了这个函数以后，我们就可以这来玩了：</p>
<pre class="brush: jscript; title: ; notranslate" title="">//艺术家
var Artist = Object.create(null);
Artist.sing = function() {
    return this.name + ' starts singing...';
}
Artist.paint = function() {
    return this.name + ' starts painting...';
}

//运动员
var Sporter = Object.create(null);
Sporter.run = function() {
    return this.name + ' starts running...';
}
Sporter.swim = function() {
    return this.name + ' starts swimming...';
}

Composition(Person, Artist);
document.write(Person.sing() + '&lt;br&gt;');
document.write(Person.paint() + '&lt;br&gt;');

Composition(Person, Sporter);
document.write(Person.run() + '&lt;br&gt;');
document.write(Person.swim() + '&lt;br&gt;');

//看看 Person中有什么？（输出：sayHello,sing,paint,swim,run）
document.write('&lt;p&gt;' + Object.keys(Person) + '&lt;br&gt;');</pre>
<h4>Prototype 和 继承</h4>
<p>我们先来说说Prototype。我们先看下面的例程，这个例程不需要解释吧，很像C语言里的函数指针，在C语言里这样的东西见得多了。</p>
<pre class="brush: jscript; title: ; notranslate" title="">var plus = function(x,y){
    document.write( x + ' + ' + y + ' = ' + (x+y) + '&lt;br&gt;');
    return x + y;
};

var minus = function(x,y){
    document.write(x + ' - ' + y + ' = ' + (x-y) + '&lt;br&gt;');
    return x - y;
};

var operations = {
    '+': plus,
    '-': minus
};

var calculate = function(x, y, operation){
    return operations[operation](x, y);
};

calculate(12, 4, '+');
calculate(24, 3, '-');</pre>
<p>那么，我们能不能把这些东西封装起来呢，我们需要使用prototype。看下面的示例：</p>
<pre class="brush: jscript; title: ; notranslate" title="">var Cal = function(x, y){
    this.x = x;
    this.y = y;
}

Cal.prototype.operations = {
    '+': function(x, y) { return x+y;},
    '-': function(x, y) { return x-y;}
};

Cal.prototype.calculate = function(operation){
    return this.operations[operation](this.x, this.y);
};

var c = new Cal(4, 5);

Cal.calculate('+');
Cal.calculate('-');</pre>
<p>这就是prototype的用法，prototype 是javascript这个语言中最重要的内容。网上有太多的文章介始这个东西了。说白了，prototype就是对一对象进行扩展，其特点在于通过“复制”一个已经存在的实例来返回新的实例,而不是新建实例。被复制的实例就是我们所称的“原型”，这个原型是可定制的（当然，这里没有真正的复制，实际只是委托）。上面的这个例子中，我们扩展了实例Cal，让其有了一个operations的属性和一个calculate的方法。</p>
<p>这样，我们可以通过这一特性来实现继承。还记得我们最最前面的那个Person吧， 下面的示例是创建一个Student来继承Person。</p>
<pre class="brush: jscript; title: ; notranslate" title="">function Person(name, email, website){
    this.name = name;
    this.email = email;
    this.website = website;
};

Person.prototype.sayHello = function(){
    var hello = "Hello, I am "+ this.name  + ", &lt;br&gt;" +
                "my email is: " + this.email + ", &lt;br&gt;" +
                "my website is: " + this.website;
    return hello;
};

function Student(name, email, website, no, dept){
    var proto = Object.getPrototypeOf;
    proto(Student.prototype).constructor.call(this, name, email, website);
    this.no = no;
    this.dept = dept;
}

// 继承prototype
Student.prototype = Object.create(Person.prototype);

//重置构造函数
Student.prototype.constructor = Student;

//重载sayHello()
Student.prototype.sayHello = function(){
    var proto = Object.getPrototypeOf;
    var hello = proto(Student.prototype).sayHello.call(this) + '&lt;br&gt;';
    hello += "my student no is: " + this. no + ", &lt;br&gt;" +
             "my departent is: " + this. dept;
    return hello;
};

var me = new Student(
    "Chen Hao",
    "haoel@hotmail.com",
    "http://coolshell.cn",
    "12345678",
    "Computer Science"
);
document.write(me.sayHello());</pre>
<h4>兼容性</h4>
<p>上面的这些代码并不一定能在所有的浏览器下都能运行，因为上面这些代码遵循 ECMAScript 5 的规范，关于ECMAScript 5 的浏览器兼容列表，你可以看这里“<a onclick="pageTracker._trackPageview('/outgoing/kangax.github.com/es5-compat-table/?referer=http%3A%2F%2Fweibo.com%2Fzzlau%3Fwvr%3D4%26lf%3Dreg%26page%3D3%26pre_page%3D2%26end_id%3D3399859468127472');" href="http://kangax.github.com/es5-compat-table/" target="_blank">ES5浏览器兼容表</a>”。</p>
<p>本文中的所有代码都在Chrome最新版中测试过了。</p>
<p>下面是一些函数，可以用在不兼容ES5的浏览器中：</p>
<h5>Object.create()函数</h5>
<pre class="brush: jscript; title: ; notranslate" title="">function clone(proto) {
    function Dummy() { }

    Dummy.prototype             = proto;
    Dummy.prototype.constructor = Dummy;

    return new Dummy(); //等价于Object.create(Person);
}

var me = clone(Person);</pre>
<h5>defineProperty()函数</h5>
<pre class="brush: jscript; title: ; notranslate" title="">function defineProperty(target, key, descriptor) {
    if (descriptor.value){
        target[key] = descriptor.value;
    }else {
        descriptor.get &amp;&amp; target.__defineGetter__(key, descriptor.get);
        descriptor.set &amp;&amp; target.__defineSetter__(key, descriptor.set);
    }

    return target
}</pre>
<h5>keys()函数</h5>
<pre class="brush: jscript; title: ; notranslate" title="">function keys(object) { var result, key
    result = [];
    for (key in object){
        if (object.hasOwnProperty(key))  result.push(key)
    }

    return result;
}</pre>
<h5>Object.getPrototypeOf() 函数</h5>
<pre class="brush: jscript; title: ; notranslate" title="">function proto(object) {
    return object?            object.__proto__
         : /* not object? */  null
}</pre>
<h4>参考</h4>
<ul>
<li>W3CSchool</li>
<li>MDN (Mozilla Developer Network)</li>
<li>MSDN (Microsoft Software Development Network)</li>
</ul>
<p><a href="http://coolshell.cn/articles/6441.html">http://coolshell.cn/articles/6441.html</a></p>
<p><span style="color: #cc0000;"><strong><br />
</strong></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhblog.net/archives/955.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>7 ‘Scroll to Top’ jQuery Solutions</title>
		<link>http://www.zhblog.net/archives/950.html</link>
		<comments>http://www.zhblog.net/archives/950.html#comments</comments>
		<pubDate>Tue, 03 Jan 2012 13:23:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[编程其他]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[javascript技巧]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.zhblog.net/?p=950</guid>
		<description><![CDATA[1. jQuery topLink Plugin The topLink jQuery plugin developed by David Walsh, allows you to fade in a “to the top” link when the users scrolls down on the page. 2. Disappearing “Scroll to top” link with jQuery and CSS This tutorial will help you build a scroll to top link, that appears when the [...]]]></description>
			<content:encoded><![CDATA[<h3><a href="http://davidwalsh.name/jquery-top-link" target="_blank">1. jQuery topLink Plugin</a></h3>
<p>The topLink <a href="http://www.zhblog.net/archives/tag/jquery" class="st_tag internal_tag" rel="tag" title="标签 jquery 下的日志">jQuery</a> plugin developed by David Walsh, allows you to fade in a “to the top” link when the users scrolls down on the page.</p>
<p><img class="pic" src="http://www.net-kit.com/wp-content/uploads/2010/02/jquery-toplink.gif" alt="jQuery topLink Plugin" width="585" height="183" /></p>
<div class="entitle">
<h3><a href="http://briancray.com/2009/10/06/scroll-to-top-link-jquery-css/" target="_blank">2. Disappearing “Scroll to top” link with jQuery and CSS</a></h3>
</div>
<p>This tutorial will help you build a scroll to top link, that appears when the user scrolls down, and disappears when users reach the top of the page using a combination of CSS and jQuery.<span id="more-950"></span></p>
<p><img class="pic" src="http://www.net-kit.com/wp-content/uploads/2010/02/scroll-to-top-link-jquery-css.gif" alt="Disappearing 'Scroll to top' link" width="585" height="183" /></p>
<div class="entitle">
<h3><a href="http://www.cherrysave.com/jquery/create-a-hovering-scroll-to-top-button-with-jquery/" target="_blank">3. Disappearing “Scroll to top” link with jQuery and CSS</a></h3>
</div>
<p>Here’s a simple Scroll to Top button that hovers in the bottom right corner of your screen. he code is largely adapted from Brian Cray and David Walsh, but it’s a combination of the two ideas with the addition of a fade effect on the button and smooth scrolling action.</p>
<p><img class="pic" src="http://www.net-kit.com/wp-content/uploads/2010/02/jquery-hovering-scroll-to-top.gif" alt="Hovering Scroll to Top Button With JQuery" width="585" height="183" /></p>
<div class="entitle">
<h3><a href="http://blog.ph-creative.com/post/jQuery-Plugin-Scroll-to-Top-v3.aspx" target="_blank">4. jQuery Plugin: Scroll to Top</a></h3>
</div>
<p>Here’s an unobtrusive, easy-to-install, jQuery script that adds a fading scroll to top link with animated scrolling. the script degrades gracefully, leaving nothing but a normal &lt;a href &gt; link.</p>
<p><img class="pic" src="http://www.net-kit.com/wp-content/uploads/2010/02/scroll-to-top-jquery-plugin.gif" alt="jQuery Plugin Scroll to Top" width="585" height="183" /></p>
<div class="entitle">
<h3><a href="http://www.mattvarone.com/web-design/uitotop-jquery-plugin/" target="_blank">5. UItoTop jQuery Plugin</a></h3>
</div>
<p>Inspired by the great idea of David Walsh’s jQuery topLink Plugin, Matt Varone made a similar plugin but with two key differences, this one does not require you to add extra html markup or extra plugins to function. It will only work when <a href="http://www.zhblog.net/archives/tag/javascript" class="st_tag internal_tag" rel="tag" title="标签 javascript 下的日志">JavaScript</a> is turned on.</p>
<p><img class="pic" src="http://www.net-kit.com/wp-content/uploads/2010/02/top-page-jquery.gif" alt="UItoTop jQuery Plugin" width="585" height="183" /></p>
<div class="entitle">
<h3><a href="http://www.dynamicdrive.com/dynamicindex3/scrolltop.htm" target="_blank">6. jQuery Scroll to Top Control v1.1 </a></h3>
</div>
<p>This script displays a stationary control at the lower right corner of the window that when clicked on gently scrolls the page back up to the top. Instead of always being visible on the user’s screen, the script lets you specify how far down the page the user is at (in pixels) before revealing the control.</p>
<p><img class="pic" src="http://www.net-kit.com/wp-content/uploads/2010/02/scroll-to-top-control-jquery.gif" alt="jQuery Scroll to Top Control" width="585" height="183" /></p>
<div class="entitle">
<h3><a href="http://blog.mogosanu.ro/css/go-to-top-of-page-animat-cu-jquery/" target="_blank">7. Smooth GoToTop WordPress plugin </a></h3>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.zhblog.net/archives/950.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>如何获取Skydrive音乐的外链</title>
		<link>http://www.zhblog.net/archives/940.html</link>
		<comments>http://www.zhblog.net/archives/940.html#comments</comments>
		<pubDate>Mon, 19 Dec 2011 08:27:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[编程其他]]></category>
		<category><![CDATA[skydrive]]></category>

		<guid isPermaLink="false">http://www.zhblog.net/?p=940</guid>
		<description><![CDATA[现在我们要上传一首”Mix”的音乐并得到其外链，关于注册账号以及新建文件夹请移步到http://lqcc.info/technical-overview/website-operators-technical-overview/skydirve-picture-outside-the-chain.html 查看。 1上传歌曲，如图: 2上传好歌曲列表页面顶部地址复制id=部分后的785AFBBC20E026A6%21121 3放在http://storage.live.com/items/后得到地址http://storage.live.com/items/785AFBBC20E026A6%21121 在新页面打开得到一个如图的xml文本 4我们需要对应歌曲的ResourceID和RelationshipName部分。 我们上传的歌曲Mix 的ResourceID是 785AFBBC20E026A6!126 RelationshipName是Mix.mp3 skydrive外链音乐格式为http://storage.live.com/items/ResourceID/?RelationshipName 这样我们上传的Mix最后的地址就是 http://storage.live.com/items/785AFBBC20E026A6!126?Mix.mp3 转自：http://www.lqcc.info/sharing-pioneer/how-to-get-music-outside-the-chain-of-skydrive.html]]></description>
			<content:encoded><![CDATA[<p>现在我们要上传一首”Mix”的音乐并得到其外链，关于注册账号以及新建文件夹请移步到<a title="SkyDrive图片外链教程" href="http://lqcc.info/technical-overview/website-operators-technical-overview/skydirve-picture-outside-the-chain.html" target="_blank">http://lqcc.info/technical-overview/website-operators-technical-overview/skydirve-picture-outside-the-chain.html</a> 查看。</p>
<p>1上传歌曲，如图:</p>
<p><a href="http://public.sn2.livefilestore.com/y1pZnr9G3zJAksAs8VwXsE7Z0PMvM3nMJsQGadIap1PIEJ9LHNH7idIMacuVOo1_5MeQu0pvwmOzXbcA8K7SO78qQ/sky-01.png"><img title="上传歌曲" src="http://public.sn2.livefilestore.com/y1pZnr9G3zJAksAs8VwXsE7Z0PMvM3nMJsQGadIap1PIEJ9LHNH7idIMacuVOo1_5MeQu0pvwmOzXbcA8K7SO78qQ/sky-01.png" alt="" width="401" height="112" /></a></p>
<p>2上传好歌曲列表页面顶部地址复制id=部分后的785AFBBC20E026A6%21121</p>
<p><a href="http://public.sn2.livefilestore.com/y1pTndTJzcX6lLKmRGb3KmS5oriVO9CW_kbWtamgRO1_ZsP_s9WA8UKHCDHzEwrh8BB-prEaLm1hkD8P81Kf-NPFg/sky-02.png"><img title="复制id=部分后的文字" src="http://public.sn2.livefilestore.com/y1pTndTJzcX6lLKmRGb3KmS5oriVO9CW_kbWtamgRO1_ZsP_s9WA8UKHCDHzEwrh8BB-prEaLm1hkD8P81Kf-NPFg/sky-02.png" alt="" width="401" height="112" /></a></p>
<p>3放在http://storage.live.com/items/后得到地址<a href="http://storage.live.com/items/785AFBBC20E026A6%21121">http://storage.live.com/items/785AFBBC20E026A6%21121</a></p>
<p>在新页面打开得到一个如图的xml文本<span id="more-940"></span></p>
<p><a href="http://public.sn2.livefilestore.com/y1pykYvpALE8GOES1jOdgu2A2z8omq-OQbyKisoGceMMs7l_Fk1cVKTzoX70M0yPpeGASOqdky1oXlH5ZiUGHRWWg/sky-03.png"><img title="得到一个xml文本" src="http://public.sn2.livefilestore.com/y1pykYvpALE8GOES1jOdgu2A2z8omq-OQbyKisoGceMMs7l_Fk1cVKTzoX70M0yPpeGASOqdky1oXlH5ZiUGHRWWg/sky-03.png" alt="" width="401" height="112" /></a></p>
<p>4我们需要对应歌曲的ResourceID和RelationshipName部分。</p>
<p>我们上传的歌曲Mix 的ResourceID是 785AFBBC20E026A6!126</p>
<p>RelationshipName是Mix.mp3</p>
<blockquote><p>skydrive外链音乐格式为http://storage.live.com/items/ResourceID/?RelationshipName</p></blockquote>
<p>这样我们上传的Mix最后的地址就是</p>
<p><a href="http://storage.live.com/items/785AFBBC20E026A6!126?Mix.mp3">http://storage.live.com/items/785AFBBC20E026A6!126?Mix.mp3</a></p>
<p>转自：<a href="http://www.lqcc.info/sharing-pioneer/how-to-get-music-outside-the-chain-of-skydrive.html">http://www.lqcc.info/sharing-pioneer/how-to-get-music-outside-the-chain-of-skydrive.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhblog.net/archives/940.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://storage.live.com/items/785AFBBC20E026A6!126?Mix.mp3" length="3233773" type="audio/mpeg" />
		</item>
		<item>
		<title>8个图片展示jQuery插件及教程</title>
		<link>http://www.zhblog.net/archives/920.html</link>
		<comments>http://www.zhblog.net/archives/920.html#comments</comments>
		<pubDate>Fri, 04 Nov 2011 09:00:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[编程其他]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.zhblog.net/?p=920</guid>
		<description><![CDATA[1. Nivo Slider Nivo Slider是世界知名的轻量级jQuery图片幻灯片插件，可以制作出很漂亮的效果。它完全免费且彻底开源。 2. Sponsor Flip Wall With jQuery &#38; CSS Sponsor Flip Wall是一个非常不错的显示数据到网格里的插件，它使用PHP、CSS与jQuery翻转插件制作而成，其实就是为了创建一个翻转赞助商页面。可以用来展示你的客户或生成一个整洁的翻转动画组合项目。  3. PhotoSwipe PhotoSwipe是一个免费的基于HTML/CSS/j的图片画廊插件，尤其可用于移动设备。 4. TN3 Gallery TN3 Gallery也是一个jQuery图片画廊和幻灯片展示插件，支持多种转换效果及多相簿选项，可定制CSS皮肤等。它适用于所有的桌面及移动浏览器。 5. SIDEWAYS – jQuery fullscreen image gallery 一个简单而又飘逸的全屏图片画廊插件，由jQuery框架及一些简单的CSS创建。 6. Moleskine Notebook with jQuery Booklet 在这篇文章中，你可以学习到如何设计一个虚拟的Moleskine笔记本。 7. Orbit: A Slick jQuery Image Slider Plugin Orbit是由ZURB开发的一个jQuery幻灯片插件。该插件非常轻量级（只有4KB），容易使用且拥有许多好功能。 8. Exposure Exposure是一个图片预览插件，用于创建丰富、自定义的视觉体验，可以处理海量数据。]]></description>
			<content:encoded><![CDATA[<p><strong>1. <span style="color: #006699;">Nivo Slider</span></strong></p>
<p>Nivo Slider是世界知名的轻量级jQuery图片幻灯片插件，可以制作出很漂亮的效果。它完全免费且彻底开源。</p>
<p><img src="http://dl.iteye.com/upload/attachment/580245/1ee4e183-38ee-3e9a-8c73-35057c01c2e3.jpeg" alt="" /><br />
<strong>2. <span style="color: #006699;">Sponsor Flip Wall With <a href="http://www.zhblog.net/archives/tag/jquery" class="st_tag internal_tag" rel="tag" title="标签 jquery 下的日志">jQuery</a> &amp; CSS</span></strong></p>
<p>Sponsor Flip Wall是一个非常不错的显示数据到网格里的插件，它使用PHP、CSS与jQuery翻转插件制作而成，其实就是为了创建一个翻转赞助商页面。可以用来展示你的客户或生成一个整洁的翻转<a href="http://flash.zol.com.cn/" target="_blank">动画</a>组合项目。 <span id="more-920"></span></p>
<p><img src="http://dl.iteye.com/upload/attachment/580247/5afd26eb-2450-3c01-ae08-46696dff27b0.jpeg" alt="" /><br />
<strong>3. <span style="color: #006699;">PhotoSwipe</span></strong></p>
<p>PhotoSwipe是一个免费的基于HTML/CSS/j的图片画廊插件，尤其可用于移动设备。</p>
<p><img src="http://dl.iteye.com/upload/attachment/580249/59ca5f64-237a-3c48-8a9a-248e90ae2a22.jpeg" alt="" /><br />
<strong>4. <span style="color: #006699;">TN3 Gallery</span></strong></p>
<p>TN3 Gallery也是一个jQuery图片画廊和幻灯片展示插件，支持多种转换效果及多相簿选项，可定制CSS皮肤等。它适用于所有的桌面及移动浏览器。</p>
<p><img src="http://dl.iteye.com/upload/attachment/580251/ba46a321-7be8-3854-9627-408f85985406.jpeg" alt="" /><br />
<strong>5. <span style="color: #006699;">SIDEWAYS – jQuery fullscreen image gallery</span></strong></p>
<p>一个简单而又飘逸的全屏图片画廊插件，由jQuery框架及一些简单的CSS创建。</p>
<p><img src="http://dl.iteye.com/upload/attachment/580253/16e8f079-ac5b-3599-b5f1-51a68cc39232.jpeg" alt="" /><br />
<strong>6. <span style="color: #006699;">Moleskine Notebook with jQuery Booklet</span></strong></p>
<p>在这篇文章中，你可以学习到如何设计一个虚拟的Moleskine<a href="http://detail.zol.com.cn/notebook_index/subcate16_list_1.html" target="_blank">笔记本</a>。</p>
<p><img src="http://dl.iteye.com/upload/attachment/580255/0d6357e0-0c56-3ea6-bddd-fd486f732edb.jpeg" alt="" /><br />
<strong>7. <span style="color: #006699;">Orbit: A Slick jQuery Image Slider Plugin</span></strong></p>
<p>Orbit是由ZURB开发的一个jQuery幻灯片插件。该插件非常轻量级（只有4KB），容易使用且拥有许多好功能。</p>
<p><img src="http://dl.iteye.com/upload/attachment/580257/ad1ac5a2-0a82-39b7-b3d5-dd1485b77355.jpeg" alt="" /><br />
<strong>8. <span style="color: #006699;">Exposure</span></strong></p>
<p>Exposure是一个图片预览插件，用于创建丰富、自定义的视觉体验，可以处理海量数据。</p>
<p><img src="http://dl.iteye.com/upload/attachment/580259/14233ce0-8860-3178-aaf8-f3eb8cbaf5f9.jpeg" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhblog.net/archives/920.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>27 个漂亮的 Web 导航设计例子</title>
		<link>http://www.zhblog.net/archives/912.html</link>
		<comments>http://www.zhblog.net/archives/912.html#comments</comments>
		<pubDate>Sat, 15 Oct 2011 11:26:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[编程其他]]></category>

		<guid isPermaLink="false">http://www.zhblog.net/?p=912</guid>
		<description><![CDATA[Handle With Love 　　整洁和有组织的垂直导航。惊人的漂亮图片和颜色！ Weightshift 　　很酷的使用菜单导航，优雅！ Don’t throw Batteries 　　优雅整洁的菜单 FA Design 　　Another great example of typography based menu. Album Art Collection 　　Amazing layout, navigation and menu. Polyester Studio 　　Awesome colours with integrated menu and flow. It never gets boring. Doopsuiker Poppies 　　Pretty menu, nice flow and navigation. simpleasmilk.co.uk 　　Good typography based layout and menu [...]]]></description>
			<content:encoded><![CDATA[<p><strong><a href="http://www.handlewithlove.net/" target="_blank">Handle With Love</a></strong></p>
<p style="text-align: center;"><a href="http://www.handlewithlove.net/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133216_1.jpg" alt="Handle With Love" /></a></p>
<p>　　整洁和有组织的垂直导航。惊人的漂亮图片和颜色！</p>
<p><span id="more-912"></span><br />
<hr />
<p><strong><a href="http://weightshift.com/" target="_blank">Weightshift</a></strong></p>
<p style="text-align: center;"><a href="http://weightshift.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133216_2.jpg" alt="Weightshift" /></a></p>
<p>　　很酷的使用菜单导航，优雅！</p>
<hr />
<p><strong><a href="http://dontthrowbatteries.com/" target="_blank">Don’t throw Batteries</a></strong></p>
<p style="text-align: center;"><a href="http://dontthrowbatteries.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133216_3.jpg" alt="Don’t throw Batteries " /></a></p>
<p>　　优雅整洁的菜单</p>
<hr />
<p><strong><a href="http://fa-d.com/" target="_blank">FA Design</a></strong></p>
<p style="text-align: center;"><a href="http://fa-d.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133216_4.jpg" alt="FA Design " /></a></p>
<p>　　Another great example of typography based menu.</p>
<hr />
<p><strong><a href="http://albumartcollection.com/" target="_blank">Album Art Collection</a></strong></p>
<p style="text-align: center;"><a href="http://albumartcollection.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133216_5.jpg" alt="Album Art Collection " /></a></p>
<p>　　Amazing layout, navigation and menu.</p>
<hr />
<p><strong><a href="http://www.polyesterstudio.com/" target="_blank">Polyester Studio</a></strong></p>
<p style="text-align: center;"><a href="http://www.polyesterstudio.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133216_6.jpg" alt="Polyester Studio" /></a></p>
<p>　　Awesome colours with integrated menu and flow. It never gets boring.</p>
<hr />
<p><strong><a href="http://www.doopsuikerpoppies.be/index.php" target="_blank">Doopsuiker Poppies</a></strong></p>
<p style="text-align: center;"><a href="http://www.doopsuikerpoppies.be/index.php"><img src="http://pic004.cnblogs.com/news/201110/20111014_133216_7.jpg" alt="Doopsuiker Poppies" /></a></p>
<p>　　Pretty menu, nice flow and navigation.</p>
<hr />
<p><strong><a href="http://simpleasmilk.co.uk/" target="_blank">simpleasmilk.co.uk</a></strong></p>
<p style="text-align: center;"><a href="http://simpleasmilk.co.uk/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_8.jpg" alt="http://simpleasmilk.co.uk/" /></a></p>
<p>　　Good typography based layout and menu with really cool colors and nice flow.</p>
<hr />
<p><strong><a href="http://www.iwc.com/" target="_blank">IWC</a></strong></p>
<p style="text-align: center;"><a href="http://www.iwc.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_9.jpg" alt="IWC" /></a></p>
<p>　　Neat grid navigation layout with a graceful menu.</p>
<hr />
<p><strong><a href="http://www.princestreetfilms.com/" target="_blank">Prince Street Films</a></strong></p>
<p style="text-align: center;"><a href="http://www.princestreetfilms.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_10.jpg" alt="Prince Street Films" /></a></p>
<p>　　Pretty good layout, colors and typography.</p>
<hr />
<p><strong><a href="http://www.comicsanscriminal.com/" target="_blank">Comic Sans Criminal</a></strong></p>
<p style="text-align: center;"><a href="http://www.comicsanscriminal.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_11.jpg" alt="Comic Sans Criminal" /></a></p>
<p>　　Horizontal vertical, based on typography and a good color scheme.</p>
<hr />
<p><strong><a href="http://abovethefoldbook.com/" target="_blank">Above the Fold</a></strong></p>
<p style="text-align: center;"><a href="http://abovethefoldbook.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_12.jpg" alt="Above the Fold" /></a></p>
<p>　　Awesome vertical navigation. You can scroll it down or select an option at the menu — both ways it is good.</p>
<hr />
<p><strong><a href="http://www.accxmedia.com/" target="_blank">ACC Media</a></strong></p>
<p style="text-align: center;"><a href="http://www.accxmedia.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_13.jpg" alt="ACC Media" /></a></p>
<p>　　Great horizontal navigation totally based on images.</p>
<hr />
<p><strong><a href="http://www.futurefabric.co.uk/" target="_blank">Futurefabric</a></strong></p>
<p style="text-align: center;"><a href="http://www.futurefabric.co.uk/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_14.jpg" alt="Futurefabric" /></a></p>
<p>　　Simple structure with scroll based navigation and beautiful menu. Simplicity is the beauty.</p>
<hr />
<p><strong><a href="http://www.polargold.de/" target="_blank">polargold</a></strong></p>
<p style="text-align: center;"><a href="http://www.polargold.de/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_15.jpg" alt="polargold" /></a></p>
<p>　　Simply hover and then click the menu you wish to open. Simple and beautiful.</p>
<hr />
<p><strong><a href="http://www.helmy-bern.cz/" target="_blank">Helmy Bern</a></strong></p>
<p style="text-align: center;"><a href="http://www.helmy-bern.cz/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_16.jpg" alt="Helmy Bern " /></a></p>
<p>　　This website has a combo hover + dropdown, which is always interesting and cool.</p>
<hr />
<p><strong><a href="http://www.voltagead.com/" target="_blank">Voltage</a></strong></p>
<p style="text-align: center;"><a href="http://www.voltagead.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_17.jpg" alt="Voltage" /></a></p>
<p>　　Large typography that gets noticed and then it fades when you are not checking out the respective menu.</p>
<hr />
<p><strong><a href="http://ecoforms.com/" target="_blank">Ecoforms</a></strong></p>
<p style="text-align: center;"><a href="http://ecoforms.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_18.jpg" alt="Ecoforms" /></a></p>
<p>　　Pretty layout and colors. Use image slider or menu to navigate easily.</p>
<hr />
<p><strong><a href="http://www.keithcakes.com.au/" target="_blank">Keith Homemade Cakes</a></strong></p>
<p style="text-align: center;"><a href="http://www.keithcakes.com.au/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_19.jpg" alt="Keith Homemade Cakes" /></a></p>
<p>　　Beautiful layout and images with easy navigation.</p>
<hr />
<p><strong><a href="http://jstraining.de/" target="_blank">Javascript für Designer</a></strong></p>
<p style="text-align: center;"><a href="http://jstraining.de/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_20.jpg" alt="Javascript für Designer" /></a></p>
<p>　　Vertical navigation with amazing color scheme and forms.</p>
<hr />
<p><strong><a href="http://ednacional.com/" target="_blank">Ed Nacional</a></strong></p>
<p style="text-align: center;"><a href="http://ednacional.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_21.jpg" alt="Ed Nacional" /></a></p>
<p>　　Neat and clean layout with eye catching images and navigation.</p>
<hr />
<p><strong><a href="http://www.marcorotoli.com/" target="_blank">Marco Rotoli</a></strong></p>
<p style="text-align: center;"><a href="http://www.marcorotoli.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_22.jpg" alt="Marco Rotoli" /></a></p>
<p>　　Use the sliders, sideways and upside down, or menus for extremely easy navigation.</p>
<hr />
<p><strong><a href="http://www.makr.com/" target="_blank">Makr Carry Goods</a></strong></p>
<p style="text-align: center;"><a href="http://www.makr.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_23.jpg" alt="Makr Carry Goods" /></a></p>
<p>　　Extremely neat layout and navigation.</p>
<hr />
<p><strong><a href="http://www.pentagram.com/" target="_blank">Pentagram</a></strong></p>
<p style="text-align: center;"><a href="http://www.pentagram.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_24.jpg" alt="Pentagram" /></a></p>
<p>　　Navigate using the horizontal sliders, images or the dropdowns. Really nice.</p>
<hr />
<p><strong><a href="http://keenanwells.com/" target="_blank">Keenan Wells</a></strong></p>
<p style="text-align: center;"><a href="http://keenanwells.com/"><img src="http://pic004.cnblogs.com/news/201110/20111014_133217_25.jpg" alt="Keenan Wells" /></a></p>
<p>　　Great navigation. All you have to do is to choose what do you wish to see in the top right corner and then just go with the flow. A horizontal slider is also present to see previous projects.</p>
<hr />
<p><strong><a href="http://www.introzo.com/">TROZO GALLERY</a></strong></p>
<p style="text-align: center;"><a href="http://www.introzo.com/"><img title="TROZO GALLERY" src="http://pic004.cnblogs.com/news/201110/20111014_133218_26.jpg" alt="TROZO GALLERY" /></a></p>
<hr />
<p><strong><a href="http://www.biola.edu/undergrad/">Biola Undergrad</a></strong></p>
<p style="text-align: center;"><a href="http://www.biola.edu/undergrad/"><img title="Biola Undergrad" src="http://pic004.cnblogs.com/news/201110/20111014_133218_27.jpg" alt="Biola Undergrad" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhblog.net/archives/912.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>7 个漂亮的 jQuery 照片插件</title>
		<link>http://www.zhblog.net/archives/910.html</link>
		<comments>http://www.zhblog.net/archives/910.html#comments</comments>
		<pubDate>Fri, 14 Oct 2011 05:45:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[编程其他]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.zhblog.net/?p=910</guid>
		<description><![CDATA[本文向你介绍 7 款很漂亮的相片展示的 jQuery 插件，提供在线演示和免费下载。 1. 交互式相片桌面，使用 jQuery 和 CSS3 开发 Demo Download 　　2. 相册缩略图导航 Demo Download 　　3. 最小化的滑动展示相册 Demo Download 　　4. 独特的相册，使用 z-index 和 jQuery 开发 Demo Download 　　5. 宝丽来相片浏览 Demo Download 　　6. Photoshoot plug-in Demo Download 　　7. Revealing Slider Demo Download]]></description>
			<content:encoded><![CDATA[<p>本文向你介绍 7 款很漂亮的相片展示的 <a href="http://www.zhblog.net/archives/tag/jquery" class="st_tag internal_tag" rel="tag" title="标签 jquery 下的日志">jQuery</a> 插件，提供在线演示和免费下载。</p>
<p>1. 交互式相片桌面，使用 jQuery 和 CSS3 开发</p>
<p><a title="Interactive Photo Desk with jQuery and CSS3" href="http://tympanus.net/Development/PhotoDesk/" target="_blank">Demo</a> <a title="Interactive Photo Desk with jQuery and CSS3" href="http://tympanus.net/codrops/2010/07/01/interactive-photo-desk/" target="_blank"> Download</a></p>
<p style="text-align: center;"><a href="http://pic004.cnblogs.com/news/201110/20111014_075453_1.jpg" rel="wp-prettyPhoto[g60]"><img title="interact" src="http://pic004.cnblogs.com/news/201110/20111014_075454_2.jpg" alt="interact" /><span id="more-910"></span></a></p>
<p>　　2. 相册缩略图导航</p>
<p><a title="Thumbnails Navigation Gallery with JQuery" href="http://tympanus.net/Tutorials/ThumbnailsNavigationGallery" target="_blank">Demo</a> <a title="Thumbnails Navigation Gallery with JQuery" href="http://tympanus.net/codrops/2010/07/29/thumbnails-navigation-gallery" target="_blank"> Download</a></p>
<p style="text-align: center;"><a href="http://pic004.cnblogs.com/news/201110/20111014_075454_3.jpg" rel="wp-prettyPhoto[g60]"><img title="sabastian" src="http://pic004.cnblogs.com/news/201110/20111014_075455_4.jpg" alt="sabastian" /></a></p>
<p>　　3. 最小化的滑动展示相册</p>
<p><a title="Minimalistic Slideshow Gallery" href="http://tympanus.net/Tutorials/MinimalisticSlideshowGallery" target="_blank">Demo</a> <a title="Minimalistic Slideshow Gallery" href="http://tympanus.net/codrops/2010/07/05/minimalistic-slideshow-gallery" target="_blank"> Download</a></p>
<p style="text-align: center;"><a href="http://pic004.cnblogs.com/news/201110/20111014_075455_5.jpg" rel="wp-prettyPhoto[g60]"><img title="minimalistic_slide" src="http://pic004.cnblogs.com/news/201110/20111014_075455_6.jpg" alt="minimalistic_slide" /></a></p>
<p>　　4. 独特的相册，使用 z-index 和 jQuery 开发</p>
<p><a title="Unique Gallery Using z-index and JQuery" href="http://demos.usejquery.com/03_z-index_gallery" target="_blank">Demo</a> <a title="Unique Gallery Using z-index and JQuery" href="http://usejquery.com/posts/3/create-a-unique-gallery-by-using-z-index-and-jquery" target="_blank"> Download</a></p>
<p style="text-align: center;"><a href="http://pic004.cnblogs.com/news/201110/20111014_075456_7.jpg" rel="wp-prettyPhoto[g60]"><img title="zindexandcss" src="http://pic004.cnblogs.com/news/201110/20111014_075456_8.jpg" alt="zindexandcss" /></a></p>
<p>　　5. 宝丽来相片浏览</p>
<p><a title="Polaroid photo viewer with CSS3 and JQuery" href="http://demo.marcofolio.net/polaroid_photo_viewer" target="_blank">Demo</a> <a title="Polaroid photo viewer with CSS3 and JQuery" href="http://www.marcofolio.net/webdesign/creating_a_polaroid_photo_viewer_with_css3_and_jquery.html" target="_blank"> Download</a></p>
<p style="text-align: center;"><a href="http://pic004.cnblogs.com/news/201110/20111014_075456_9.jpg" rel="wp-prettyPhoto[g60]"><img title="polaroid" src="http://pic004.cnblogs.com/news/201110/20111014_075457_10.jpg" alt="polaroid" /></a></p>
<p>　　6. Photoshoot plug-in</p>
<p><a title="Photoshoot plug-in" href="http://demo.tutorialzine.com/2010/02/photo-shoot-css-jquery/demo.html" target="_blank">Demo</a> <a title="Photoshoot plug-in" href="http://tutorialzine.com/2010/02/jquery-photoshoot-plugin" target="_blank"> Download</a></p>
<p style="text-align: center;"><a href="http://pic004.cnblogs.com/news/201110/20111014_075457_11.jpg" rel="wp-prettyPhoto[g60]"><img title="photoshoot_plugin" src="http://pic004.cnblogs.com/news/201110/20111014_075457_12.jpg" alt="photoshoot_plugin" /></a></p>
<p>　　7. Revealing Slider</p>
<p><a title="Revealing Slider" href="http://css-tricks.com/examples/RevealingPhotoSlider2" target="_blank">Demo</a> <a title="Revealing Slider" href="http://css-tricks.com/revealing-photo-slider" target="_blank"> Download</a></p>
<p style="text-align: center;"><a href="http://pic004.cnblogs.com/news/201110/20111014_075457_13.jpg" rel="wp-prettyPhoto[g60]"><img title="revealing_slider" src="http://pic004.cnblogs.com/news/201110/20111014_075458_14.jpg" alt="revealing_slider" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhblog.net/archives/910.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>给初学者的30条PHP最佳实践</title>
		<link>http://www.zhblog.net/archives/901.html</link>
		<comments>http://www.zhblog.net/archives/901.html#comments</comments>
		<pubDate>Wed, 03 Aug 2011 10:19:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[编程其他]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.zhblog.net/?p=901</guid>
		<description><![CDATA[1，和PHP手册成为好朋友 2，打开Error Reporting Error reporting 在 PHP 开发时是很有帮助的. 你可以在你代码中发现先前你没有发现的错误，因为并不是所有的BUG都会让程序运行不了的。当产品正式使用时，才有必要关掉错误报告，不然顾客看到一堆奇怪的字符不知道那是什么意思。 3，使用IDE IDE (集成开发环境，Integrated Development Environments)对于开发者来说是很有帮助的工具. 荒野在这里推荐netbeans IDE 。 4. 试着使用一个PHP 框架 5.学习DRY方法 DRY 代表 Don’t Repeat Yourself，它是一个有价值的编程概念，不管是什么语言。DRY编程，顾名思义，是确保你不写多余的代码。 6.使用空格缩进代码来提高可读性 7. “Tier” your Code 给你的应用程序分层，分成不同部位的不同组成部分的代码。这使得您可以轻松地在未来改变你的代码。 如常用的MVC模式。 8. 总是使用 &#60;?php ?&#62; 9.使用有意义的，一致的命名约定 10.注释、注释、注释 11.安装MAMP/WAMP 12.给你的脚本限制运行时间 通常PHP脚本的运行时间被限制为30秒，超过这个时间PHP将抛出一个致命错误。 13.使用OOP 14.知道双引号和单引号的不同 15.不要在网站的根目录放phpinfo() 16.永远不要信任你的用户 17.加密存储密码 Rebuttal: Keep in mind, however, that MD5 hashes [...]]]></description>
			<content:encoded><![CDATA[<p>1，和PHP手册成为好朋友</p>
<p>2，打开Error Reporting</p>
<p>Error reporting 在 <a href="http://www.zhblog.net/archives/tag/php" class="st_tag internal_tag" rel="tag" title="标签 php 下的日志">PHP</a> 开发时是很有帮助的. 你可以在你代码中发现先前你没有发现的错误，因为并不是所有的BUG都会让程序运行不了的。当产品正式使用时，才有必要关掉错误报告，不然顾客看到一堆奇怪的字符不知道那是什么意思。</p>
<p>3，使用IDE</p>
<p>IDE (集成开发环境，Integrated Development Environments)对于开发者来说是很有帮助的工具.</p>
<p>荒野在这里推荐netbeans IDE 。<span id="more-901"></span></p>
<p>4. 试着使用一个PHP 框架</p>
<p>5.学习DRY方法</p>
<p>DRY 代表 Don’t Repeat Yourself，它是一个有价值的编程概念，不管是什么语言。DRY编程，顾名思义，是确保你不写多余的代码。</p>
<p>6.使用空格缩进代码来提高可读性</p>
<p>7. “Tier” your Code</p>
<p>给你的应用程序分层，分成不同部位的不同组成部分的代码。这使得您可以轻松地在未来改变你的代码。 如常用的MVC模式。</p>
<p>8. 总是使用 &lt;?php ?&gt;</p>
<p>9.使用有意义的，一致的命名约定</p>
<p>10.注释、注释、注释</p>
<p>11.安装MAMP/WAMP</p>
<p>12.给你的脚本限制运行时间</p>
<p>通常PHP脚本的运行时间被限制为30秒，超过这个时间PHP将抛出一个致命错误。</p>
<p>13.使用OOP</p>
<p>14.知道双引号和单引号的不同</p>
<p>15.不要在网站的根目录放phpinfo()</p>
<p>16.永远不要信任你的用户</p>
<p>17.加密存储密码</p>
<p>Rebuttal:</p>
<blockquote><p>Keep in mind, however, that MD5 hashes have long since been compromised. They’re absolutely more secure than not, but, with the use of an enormous “rainbow table,” hackers can cross reference your hash. To add even more security, consider adding a salt as well. A salt is basically an additional set of characters that you append to the user’s string.</p></blockquote>
<p>18.使用可视化数据库设计工具</p>
<p>如 <a href="http://ihacklog.com/l.php?url=http%3A%2F%2Ffabforce.net%2Fdbdesigner4%2F" target="_blank">DBDesigner</a> 和 <a href="http://ihacklog.com/l.php?url=http%3A%2F%2Fdev.mysql.com%2Fworkbench%2F" target="_blank">MySQL Workbench</a></p>
<p>19.使用输出缓冲</p>
<p>Rebuttal: Though not required, it’s generally considered to be a good practice to go ahead and append the “ob_end_flush();” function as well to the bottom of the document. P.S. Want to compress the HTML as well? Simply replace “ob_start();” with “ob_start(‘ob_gzhandler’)”;</p>
<p>Refer to <a href="http://ihacklog.com/l.php?url=http%3A%2F%2Fdev-tips.com%2Ffeatured%2Foutput-buffering-for-web-developers-a-beginners-guide" target="_blank">this Dev-tips </a>article for more information.</p>
<div class="codecolorer-container php default" style="overflow: auto; white-space: nowrap; width: 575px;">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="line-numbers">
<div>1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
11<br />
12</div>
</td>
<td>
<div class="php codecolorer">&lt;!DOCTYPE html&gt;</p>
<p><span class="kw2">&lt;?php</span> <a href="http://www.php.net/ob_start" target="blank"><span class="kw3">ob_start</span></a><span class="br0">(</span><span class="st_h">&#8216;ob_gzhandler&#8217;</span><span class="br0">)</span><span class="sy0">;</span> <span class="sy1">?&gt;</span></p>
<p>&lt;html lang=”en”&gt;</p>
<p>&lt;head&gt;</p>
<p>&lt;meta http-equiv=”Content-Type” content=”text/html; charset=utf-8&#8243;&gt;</p>
<p>&lt;title&gt;untitled&lt;/title&gt;</p>
<p>&lt;/head&gt;</p>
<p>&lt;body&gt;&lt;/body&gt;</p>
<p>&lt;/html&gt;</p>
<p><span class="kw2">&lt;?php</span> <a href="http://www.php.net/ob_end_flush" target="blank"><span class="kw3">ob_end_flush</span></a><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span> <span class="sy1">?&gt;</span></p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<p>20.保护你的代码避免SQL注射</p>
<div class="codecolorer-container php default" style="overflow: auto; white-space: nowrap; width: 575px;">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="line-numbers">
<div>1</div>
</td>
<td>
<div class="php codecolorer"><span class="re0">$username</span> <span class="sy0">=</span> <a href="http://www.php.net/mysql_real_escape_string" target="blank"><span class="kw3">mysql_real_escape_string</span></a><span class="br0">(</span> <span class="re0">$GET</span><span class="br0">[</span><span class="st_h">'username'</span><span class="br0">]</span> <span class="br0">)</span><span class="sy0">;</span></div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="codecolorer-container php default" style="overflow: auto; white-space: nowrap; width: 575px;">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="line-numbers">
<div>1<br />
2<br />
3<br />
4</div>
</td>
<td>
<div class="php codecolorer">　　　　<span class="re0">$id</span> <span class="sy0">=</span> <span class="re0">$_GET</span><span class="br0">[</span><span class="st_h">'id'</span><span class="br0">]</span><span class="sy0">;</span></p>
<p><span class="re0">$statement</span> <span class="sy0">=</span> <span class="re0">$connection</span><span class="sy0">-&gt;</span><span class="me1">prepare</span><span class="br0">(</span> <span class="st0">“SELECT * FROM tbl_members WHERE id = ?”</span> <span class="br0">)</span><span class="sy0">;</span></p>
<p><span class="re0">$statement</span><span class="sy0">-&gt;</span><span class="me1">bind_param</span><span class="br0">(</span> <span class="st0">“i”</span><span class="sy0">,</span> <span class="re0">$id</span> <span class="br0">)</span><span class="sy0">;</span></p>
<p><span class="re0">$statement</span><span class="sy0">-&gt;</span><span class="me1">execute</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></div>
</td>
</tr>
</tbody>
</table>
</div>
<blockquote><p>By using prepared statements, we never embed the user’s inputted data directly into our query. Instead, we use the “bind_param” method to bind the values (and escaping) to the query. Much safer, and, notably, faster when executing multiple CRUD statements at once.</p></blockquote>
<p>21.尝试ORM　（object relational mapping）</p>
<p>ORM libraries for PHP like <a href="http://ihacklog.com/l.php?url=http%3A%2F%2Fpropel.phpdb.org%2Ftrac%2F" target="_blank">Propel</a>, and ORM is built into PHP frameworks like<a href="http://ihacklog.com/l.php?url=http%3A%2F%2Fcakephp.org%2F" target="_blank"> CakePHP</a>.</p>
<p>22.缓存数据库驱动页面</p>
<p>如：</p>
<div class="codecolorer-container php default" style="overflow: auto; white-space: nowrap; width: 575px;">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="line-numbers">
<div>1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
11<br />
12<br />
13<br />
14<br />
15<br />
16</div>
</td>
<td>
<div class="php codecolorer">    <span class="co1">// TOP of your script</span></p>
<p><span class="re0">$cachefile</span> <span class="sy0">=</span> <span class="st_h">&#8216;cache/&#8217;</span><span class="sy0">.</span><a href="http://www.php.net/basename" target="blank"><span class="kw3">basename</span></a><span class="br0">(</span><span class="re0">$_SERVER</span><span class="br0">[</span><span class="st_h">'SCRIPT_URI'</span><span class="br0">]</span><span class="br0">)</span><span class="sy0">;</span></p>
<p><span class="re0">$cachetime</span> <span class="sy0">=</span> <span class="nu0">120</span> <span class="sy0">*</span> <span class="nu0">60</span><span class="sy0">;</span> <span class="co1">// 2 hours</span></p>
<p><span class="co1">// Serve from the cache if it is younger than $cachetime</span></p>
<p><span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/file_exists" target="blank"><span class="kw3">file_exists</span></a><span class="br0">(</span><span class="re0">$cachefile</span><span class="br0">)</span> <span class="sy0">&amp;&amp;</span> <span class="br0">(</span><a href="http://www.php.net/time" target="blank"><span class="kw3">time</span></a><span class="br0">(</span><span class="br0">)</span> <span class="sy0">-</span> <span class="re0">$cachetime</span> <span class="sy0">&lt;</span> <a href="http://www.php.net/filemtime" target="blank"><span class="kw3">filemtime</span></a><span class="br0">(</span><span class="re0">$cachefile</span><span class="br0">)</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span></p>
<p><span class="kw1">include</span><span class="br0">(</span><span class="re0">$cachefile</span><span class="br0">)</span><span class="sy0">;</span></p>
<p><span class="kw1">echo</span> <span class="st0">“&lt;!&#8211; Cached “</span><span class="sy0">.</span><a href="http://www.php.net/date" target="blank"><span class="kw3">date</span></a><span class="br0">(</span><span class="st_h">&#8216;jS F Y H:i&#8217;</span><span class="sy0">,</span> <a href="http://www.php.net/filemtime" target="blank"><span class="kw3">filemtime</span></a><span class="br0">(</span><span class="re0">$cachefile</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">.</span><span class="st0">” &#8211;&gt;”</span><span class="sy0">;</span></p>
<p><a href="http://www.php.net/exit" target="blank"><span class="kw3">exit</span></a><span class="sy0">;</span></p>
<p><span class="br0">}</span></p>
<p><a href="http://www.php.net/ob_start" target="blank"><span class="kw3">ob_start</span></a><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span> <span class="co1">// start the output buffer</span></p>
<p><span class="co1">// Your normal PHP script and HTML content here</span></p>
<p><span class="co1">// BOTTOM of your script</span></p>
<p><span class="re0">$fp</span> <span class="sy0">=</span> <a href="http://www.php.net/fopen" target="blank"><span class="kw3">fopen</span></a><span class="br0">(</span><span class="re0">$cachefile</span><span class="sy0">,</span> <span class="st_h">&#8216;w&#8217;</span><span class="br0">)</span><span class="sy0">;</span> <span class="co1">// open the cache file for writing</span></p>
<p><a href="http://www.php.net/fwrite" target="blank"><span class="kw3">fwrite</span></a><span class="br0">(</span><span class="re0">$fp</span><span class="sy0">,</span> <a href="http://www.php.net/ob_get_contents" target="blank"><span class="kw3">ob_get_contents</span></a><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span> <span class="co1">// save the contents of output buffer to the file</span></p>
<p><a href="http://www.php.net/fclose" target="blank"><span class="kw3">fclose</span></a><span class="br0">(</span><span class="re0">$fp</span><span class="br0">)</span><span class="sy0">;</span> <span class="co1">// close the file</span></p>
<p><a href="http://www.php.net/ob_end_flush" target="blank"><span class="kw3">ob_end_flush</span></a><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span> <span class="co1">// Send the output to the browser</span></div>
</td>
</tr>
</tbody>
</table>
</div>
<p>23.使用缓存系统</p>
<ul>
<li><a href="http://www.danga.com/memcached/">Memcached</a></li>
<li><a href="http://us.php.net/manual/en/intro.apc.php">APC</a></li>
<li><a href="http://xcache.lighttpd.net/">XCache</a></li>
<li><a href="http://files.zend.com/help/Zend-Platform/zend_cache_api.htm">Zend Cache</a></li>
<li><a href="http://www.eaccelerator.net/">eAccelerator</a></li>
</ul>
<p>24.验证Cookie数据</p>
<p>Cookie data, like any data passed on the Web, can be harmful. You can validate cookie data with either the htmlspecialchars() or mysql_real_escape_string().</p>
<p>25.使用静态文件缓存系统</p>
<p>如Smarty的是一个内置缓存的强大的模板系统。</p>
<p>26.分析你的代码</p>
<p>Profiling your code with a tool like xdebug can help you to quickly spot bottlenecks and other potential problems in your PHP code. Some IDEs like Netbeans have PHP profiling capabilities as well.</p>
<p>27.编码标准</p>
<p>如 <a class="sy0" style="overflow: auto; white-space: nowrap; width: 575px;" href="http://ihacklog.com/l.php?url=http%3A%2F%2Fnet.tutsplus.com%2Ftutorials%2Fphp%2F30-php-best-practices-for-beginners%2F" target="_blank">http://net.tutsplus.com/tutorials/php/30-php-best-practices-for-beginners/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhblog.net/archives/901.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery设计思想</title>
		<link>http://www.zhblog.net/archives/899.html</link>
		<comments>http://www.zhblog.net/archives/899.html#comments</comments>
		<pubDate>Wed, 27 Jul 2011 06:13:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[编程其他]]></category>
		<category><![CDATA[java web]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[javascript学习]]></category>
		<category><![CDATA[javascript技巧]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.zhblog.net/?p=899</guid>
		<description><![CDATA[据统计，全世界排名前100万的网站，有46%使用jQuery，远远超过其他库。微软公司甚至把jQuery作为他们的官方库。 对于网页开发者来说，学会jQuery是必要的。因为它让你了解业界最通用的技术，为将来学习更高级的库打下基础，并且确实可以很轻松地做出许多复杂的效果。 虽然jQuery上手简单，比其他库容易学会，但是要全面掌握，却不轻松。因为它涉及到网页开发的方方面面，提供的各种方法和内部变化有上千种之多。初学者常常感到，入门很方便，提高很困难。 目前，互联网上最好的jQuery入门教材，是Rebecca Murphey写的《jQuery基础》（jQuery Fundamentals）。在Google里搜索”jQuery 培训”，此书排在第一位。jQuery官方团队已经同意，把此书作为官方教程的基础。 这本书虽然是入门教材，但也足足有100多页。我对它做了一个详细的笔记，试图理清jQuery的设计思想，找出学习的脉络。我的目标是全面掌握jQuery，遇到问题的时候，心里有底，基本知道使用它的哪一个功能，然后可以迅速从手册中找到具体的写法。 下面就是我的笔记，它应该是目前网上不多的jQuery中文教程之一。你只需要一点javascript语言的基本知识，就能看懂它，在最短的时间里，掌握jQuery的所有主要方面（除了ajax和插件开发）。 =========================================== jQuery设计思想 原文网址：http://jqfundamentals.com/book/ 阮一峰 翻译整理 【目录】 一、选择网页元素 二、改变结果集 三、链式操作 四、元素的操作：取值和赋值 五、元素的操作：移动 六、元素的操作：复制、删除和创建 七、工具方法 八、事件操作 九、特殊效果 【正文】 一、选择网页元素 jQuery的基本设计和主要用法，就是“选择某个网页元素，然后对其进行某种操作”。这是它区别于其他函数库的根本特点。 使用jQuery的第一步，往往就是将一个选择表达式，放进构造函数jQuery()（简写为$），然后得到被选中的元素。 选择表达式可以是CSS选择器： 　　$(document) //选择整个文档对象 $(&#8216;#myId&#8217;) //选择ID为myId的网页元素 $(&#8216;div.myClass&#8217;) // 选择class为myClass的div元素 $(&#8216;input[name=first]&#8216;) // 选择name属性等于first的input元素 也可以是jQuery特有的表达式： 　　$(&#8216;a:first&#8217;) //选择网页中第一个a元素 $(&#8216;tr:odd&#8217;) //选择表格的奇数行 $(&#8216;#myForm :input&#8217;) // 选择表单中的input元素 $(&#8216;div:visible&#8217;) //选择可见的div元素 $(&#8216;div:gt(2)&#8217;) // 选择所有的div元素，除了前三个 $(&#8216;div:animated&#8217;) // [...]]]></description>
			<content:encoded><![CDATA[<p>据<a href="http://trends.builtwith.com/javascript/">统计</a>，全世界排名前100万的网站，有46%使用jQuery，远远超过其他库。微软公司甚至把jQuery作为他们的官方库。</p>
<p>对于网页开发者来说，学会jQuery是必要的。因为它让你了解业界最通用的技术，为将来学习更高级的库打下基础，并且确实可以很轻松地做出许多复杂的效果。</p>
<p>虽然jQuery上手简单，比其他库容易学会，但是要全面掌握，却不轻松。因为它涉及到网页开发的方方面面，提供的各种方法和内部变化有上千种之多。初学者常常感到，入门很方便，提高很困难。</p>
<p>目前，互联网上最好的jQuery入门教材，是<a href="http://www.rebeccamurphey.com/">Rebecca Murphey</a>写的<a href="http://jqfundamentals.com/book/index.html">《jQuery基础》</a>（<a href="http://www.zhblog.net/archives/tag/jquery" class="st_tag internal_tag" rel="tag" title="标签 jquery 下的日志">jQuery</a> Fundamentals）。在Google里搜索”<a href="http://www.zhblog.net/archives/tag/jquery" class="st_tag internal_tag" rel="tag" title="标签 jquery 下的日志">jQuery</a> 培训”，此书排在第一位。jQuery官方团队已经<a href="http://blog.rebeccamurphey.com/the-future-of-jquery-fundamentals-and-a-confe">同意</a>，把此书作为官方教程的基础。<span id="more-899"></span></p>
<p>这本书虽然是入门教材，但也足足有100多页。我对它做了一个详细的笔记，试图理清jQuery的设计思想，找出学习的脉络。我的目标是全面掌握jQuery，遇到问题的时候，心里有底，基本知道使用它的哪一个功能，然后可以迅速从<a href="http://docs.jquery.com/Main_Page">手册</a>中找到具体的写法。</p>
<p>下面就是我的笔记，它应该是目前网上不多的jQuery中文教程之一。你只需要一点javascript语言的基本知识，就能看懂它，在最短的时间里，掌握jQuery的所有主要方面（除了<a href="http://api.jquery.com/category/ajax/">ajax</a>和<a href="http://docs.jquery.com/Plugins/Authoring">插件开发</a>）。</p>
<p>===========================================</p>
<p><strong>jQuery设计思想</strong></p>
<p>原文网址：<a href="http://jqfundamentals.com/book/">http://jqfundamentals.com/book/</a></p>
<p>阮一峰 翻译整理</p>
<p>【目录】</p>
<p>一、选择网页元素</p>
<p>二、改变结果集</p>
<p>三、链式操作</p>
<p>四、元素的操作：取值和赋值</p>
<p>五、元素的操作：移动</p>
<p>六、元素的操作：复制、删除和创建</p>
<p>七、工具方法</p>
<p>八、事件操作</p>
<p>九、特殊效果</p>
<p>【正文】</p>
<p><strong>一、选择网页元素</strong></p>
<p>jQuery的基本设计和主要用法，就是<strong>“选择某个网页元素，然后对其进行某种操作”</strong>。这是它区别于其他函数库的根本特点。</p>
<p>使用jQuery的第一步，往往就是将一个选择表达式，放进构造函数jQuery()（简写为$），然后得到被选中的元素。</p>
<p>选择表达式可以是<a href="http://www.ruanyifeng.com/blog/2009/03/css_selectors.html">CSS选择器</a>：</p>
<blockquote><p>　　$(document) //选择整个文档对象</p>
<p>$(&#8216;#myId&#8217;) //选择ID为myId的网页元素</p>
<p>$(&#8216;div.myClass&#8217;) // 选择class为myClass的div元素</p>
<p>$(&#8216;input[name=first]&#8216;) // 选择name属性等于first的input元素</p></blockquote>
<p>也可以是jQuery<a href="http://api.jquery.com/category/selectors/">特有的表达式</a>：</p>
<blockquote><p>　　$(&#8216;a:first&#8217;) //选择网页中第一个a元素</p>
<p>$(&#8216;tr:odd&#8217;) //选择表格的奇数行</p>
<p>$(&#8216;#myForm :input&#8217;) // 选择表单中的input元素</p>
<p>$(&#8216;div:visible&#8217;) //选择可见的div元素</p>
<p>$(&#8216;div:gt(2)&#8217;) // 选择所有的div元素，除了前三个</p>
<p>$(&#8216;div:animated&#8217;) // 选择当前处于动画状态的div元素</p></blockquote>
<p><strong>二、改变结果集</strong></p>
<p>如果选中多个元素，jQuery提供<a href="http://api.jquery.com/category/traversing/filtering/">过滤器</a>，可以缩小结果集：</p>
<blockquote><p>　　$(&#8216;div&#8217;).has(&#8216;p&#8217;); // 选择包含p元素的div元素</p>
<p>$(&#8216;div&#8217;).not(&#8216;.myClass&#8217;); //选择class不等于myClass的div元素</p>
<p>$(&#8216;div&#8217;).filter(&#8216;.myClass&#8217;); //选择class等于myClass的div元素</p>
<p>$(&#8216;div&#8217;).first(); //选择第1个div元素</p>
<p>$(&#8216;div&#8217;).eq(5); //选择第6个div元素</p></blockquote>
<p>有时候，我们需要从结果集出发，移动到附近的相关元素，jQuery也提供了在DOM树上的<a href="http://api.jquery.com/category/traversing/tree-traversal/">移动方法</a>：</p>
<blockquote><p>　　$(&#8216;div&#8217;).next(&#8216;p&#8217;); //选择div元素后面的第一个p元素</p>
<p>$(&#8216;div&#8217;).parent(); //选择div元素的父元素</p>
<p>$(&#8216;div&#8217;).closest(&#8216;form&#8217;); //选择离div最近的那个form父元素</p>
<p>$(&#8216;div&#8217;).children(); //选择div的所有子元素</p>
<p>$(&#8216;div&#8217;).siblings(); //选择div的同级元素</p></blockquote>
<p><strong>三、链式操作</strong></p>
<p>选中网页元素以后，就可以对它进行某种操作。</p>
<p>jQuery允许将所有操作连接在一起，以链条的形式写出来，比如：</p>
<blockquote><p>　　$(&#8216;div&#8217;).find(&#8216;h3&#8242;).eq(2).html(&#8216;Hello&#8217;);</p></blockquote>
<p>分解开来，就是下面这样：</p>
<blockquote><p>　　$(&#8216;div&#8217;) //找到div元素</p>
<p>.find(&#8216;h3&#8242;) //选择其中的h3元素</p>
<p>.eq(2) //选择第3个h3元素</p>
<p>.html(&#8216;Hello&#8217;); //将它的内容改为Hello</p></blockquote>
<p>这是jQuery最令人称道、最方便的特点。它的原理在于每一步的jQuery操作，返回的都是一个jQuery对象，所以不同操作可以连在一起。</p>
<p>jQuery还提供了<a href="http://api.jquery.com/end/">.end()</a>方法，使得结果集可以后退一步：</p>
<blockquote><p>　　$(&#8216;div&#8217;)</p>
<p>.find(&#8216;h3&#8242;)</p>
<p>.eq(2)</p>
<p>.html(&#8216;Hello&#8217;)</p>
<p><strong>.end() //退回到选中所有的h3元素的那一步</strong></p>
<p>.eq(0) //选中第一个h3元素</p>
<p>.html(&#8216;World&#8217;); //将它的内容改为World</p></blockquote>
<p><strong>四、元素的操作：取值和赋值</strong></p>
<p>操作网页元素，最常见的需求是取得它们的值，或者对它们进行赋值。</p>
<p>jQuery使用同一个函数，来完成取值（getter）和赋值（setter）。到底是取值还是赋值，由函数的参数决定。</p>
<blockquote><p>　　$(&#8216;h1&#8242;).html(); //html()没有参数，表示取出h1的值</p>
<p>$(&#8216;h1&#8242;).html(&#8216;Hello&#8217;); //html()有参数Hello，表示对h1进行赋值</p></blockquote>
<p>常见的取值和赋值函数如下：</p>
<blockquote><p>　　<a href="http://api.jquery.com/html/">.html()</a> 取出或设置html内容</p>
<p><a href="http://api.jquery.com/text/">.text()</a> 取出或设置text内容</p>
<p><a href="http://api.jquery.com/attr/">.attr()</a> 取出或设置某个属性的值</p>
<p><a href="http://api.jquery.com/width/">.width()</a> 取出或设置某个元素的宽度</p>
<p><a href="http://api.jquery.com/height/">.height()</a> 取出或设置某个元素的高度</p>
<p><a href="http://api.jquery.com/val/">.val()</a> 取出某个表单元素的值</p></blockquote>
<p>需要注意的是，如果结果集包含多个元素，那么赋值的时候，将对其中所有的元素赋值；取值的时候，则是只取出第一个元素的值（<a href="http://api.jquery.com/text/">.text()</a>例外，它取出所有元素的text内容）。</p>
<p><strong>五、元素的操作：移动</strong></p>
<p>如果要移动选中的元素，有两种方法：一种是直接移动该元素，另一种是移动其他元素，使得目标元素达到我们想要的位置。</p>
<p>假定我们选中了一个div元素，需要把它移动到p元素后面。</p>
<p>第一种方法是使用<a href="http://api.jquery.com/insertAfter/">.insertAfter()</a>，把div元素移动p元素后面：</p>
<blockquote><p>　　$(&#8216;div&#8217;).insertAfter(&#8216;p&#8217;);</p></blockquote>
<p>第二种方法是使用<a href="http://api.jquery.com/after/">.after()</a>，把p元素加到div元素前面：</p>
<blockquote><p>　　$(&#8216;p&#8217;).after(&#8216;div&#8217;);</p></blockquote>
<p>表面上看，这两种方法的效果是一样的，唯一的不同似乎只是操作视角的不同。但是实际上，它们有一个重大差别，那就是返回的元素不一样。第一种方法返回div元素，第二种方法返回p元素。你可以根据需要，选择到底使用哪一种方法。</p>
<p>使用这种模式的操作方法，一共有四对：</p>
<blockquote><p>　　<a href="http://api.jquery.com/insertAfter/">.insertAfter()</a>和<a href="http://api.jquery.com/after/">.after()</a>：在现存元素的外部，从后面插入元素</p>
<p><a href="http://api.jquery.com/insertBefore/">.insertBefore()</a>和<a href="http://api.jquery.com/before">.before()</a>：在现存元素的外部，从前面插入元素</p>
<p><a href="http://api.jquery.com/appendTo/">.appendTo()</a>和<a href="http://api.jquery.com/append">.append()</a>：在现存元素的内部，从后面插入元素</p>
<p><a href="http://api.jquery.com/prependTo/">.prependTo()</a>和<a href="http://api.jquery.com/prepend">.prepend()</a>：在现存元素的内部，从前面插入元素</p></blockquote>
<p><strong>六、元素的操作：复制、删除和创建</strong></p>
<p>复制元素使用<a href="http://api.jquery.com/clone/">.clone()</a>。</p>
<p>删除元素使用<a href="http://api.jquery.com/remove/">.remove()</a>和<a href="http://api.jquery.com/detach/">.detach()</a>。两者的区别在于，前者不保留被删除元素的事件，后者保留，有利于重新插入文档时使用。</p>
<p>清空元素内容（但是不删除该元素）使用<a href="http://api.jquery.com/empty/">.empty()</a>。</p>
<p>创建新元素的方法非常简单，只要把新元素直接传入jQuery的构造函数就行了：</p>
<blockquote><p>　　$(&#8216;&lt;p&gt;Hello&lt;/p&gt;&#8217;);</p>
<p>$(&#8216;&lt;li class=”new”&gt;new list item&lt;/li&gt;&#8217;);</p>
<p>$(&#8216;ul&#8217;).append(&#8216;&lt;li&gt;list item&lt;/li&gt;&#8217;);</p></blockquote>
<p><strong>七、工具方法</strong></p>
<p>除了对选中的元素进行操作以外，jQuery还提供一些<a href="http://api.jquery.com/category/utilities/">工具方法</a>（utility），不必选中元素，就可以直接使用。</p>
<p>如果你懂得Javascript语言的<a href="http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html">继承原理</a>，那么就能理解工具方法的实质。它是定义在jQuery构造函数上的方法，即jQuery.method()，所以可以直接使用。而那些操作元素的方法，是定义在构造函数的prototype对象上的方法，即jQuery.prototype.method()，所以必须生成实例（即选中元素）后使用。如果不理解这种区别，问题也不大，只要把工具方法理解成，是像javascript原生函数那样，可以直接使用的方法就行了。</p>
<p>常用的工具方法有以下几种：</p>
<blockquote><p>　　<a href="http://api.jquery.com/jQuery.trim/">$.trim()</a> 去除字符串两端的空格。</p>
<p><a href="http://api.jquery.com/jQuery.each/">$.each()</a> 遍历一个数组或对象。</p>
<p><a href="http://api.jquery.com/jQuery.inArray/">$.inArray()</a> 返回一个值在数组中的索引位置。如果该值不在数组中，则返回-1。</p>
<p><a href="http://api.jquery.com/jQuery.grep/">$.grep()</a> 返回数组中符合某种标准的元素。</p>
<p><a href="http://api.jquery.com/jQuery.extend/">$.extend()</a> 将多个对象，合并到第一个对象。</p>
<p><a href="http://api.jquery.com/jQuery.makeArray/">$.makeArray()</a> 将对象转化为数组。</p>
<p><a href="http://api.jquery.com/jQuery.type/">$.type()</a> 判断对象的类别（函数对象、日期对象、数组对象、正则对象等等）。</p>
<p><a href="http://api.jquery.com/jQuery.isArray/">$.isArray()</a> 判断某个参数是否为数组。</p>
<p><a href="http://api.jquery.com/jQuery.isEmptyObject/">$.isEmptyObject()</a> 判断某个对象是否为空（不含有任何属性）。</p>
<p><a href="http://api.jquery.com/jQuery.isFunction/">$.isFunction()</a> 判断某个参数是否为函数。</p>
<p><a href="http://api.jquery.com/jQuery.isPlainObject/">$.isPlainObject()</a> 判断某个参数是否为用”{}”或”new Object”建立的对象。</p>
<p><a href="http://api.jquery.com/jQuery.support/">$.support()</a> 判断浏览器是否支持某个特性。</p></blockquote>
<p><strong>八、事件操作</strong></p>
<p>jQuery可以对网页元素绑定<a href="http://api.jquery.com/category/events/">事件</a>。根据不同的事件，运行相应的函数。</p>
<blockquote><p>　　$(&#8216;p&#8217;).click(function(){</p>
<p>alert(&#8216;Hello&#8217;);</p>
<p>});</p></blockquote>
<p>目前，jQuery主要支持以下事件：</p>
<blockquote><p>　　<a href="http://api.jquery.com/blur/">.blur()</a> 表单元素失去焦点。</p>
<p><a href="http://api.jquery.com/change/">.change()</a> 表单元素的值发生变化</p>
<p><a href="http://api.jquery.com/click/">.click()</a> 鼠标单击</p>
<p><a href="http://api.jquery.com/dblclick/">.dblclick()</a> 鼠标双击</p>
<p><a href="http://api.jquery.com/focus/">.focus()</a> 表单元素获得焦点</p>
<p><a href="http://api.jquery.com/focusin/">.focusin()</a> 子元素获得焦点</p>
<p><a href="http://api.jquery.com/focusout/">.focusout()</a> 子元素失去焦点</p>
<p><a href="http://api.jquery.com/hover/">.hover()</a> 同时为mouseenter和mouseleave事件指定处理函数</p>
<p><a href="http://api.jquery.com/keydown/">.keydown()</a> 按下键盘（长时间按键，只返回一个事件）</p>
<p><a href="http://api.jquery.com/keypress/">.keypress()</a> 按下键盘（长时间按键，将返回多个事件）</p>
<p><a href="http://api.jquery.com/keyup/">.keyup()</a> 松开键盘</p>
<p><a href="http://api.jquery.com/load-event/">.load()</a> 元素加载完毕</p>
<p><a href="http://api.jquery.com/mousedown/">.mousedown()</a> 按下鼠标</p>
<p><a href="http://api.jquery.com/mouseenter/">.mouseenter()</a> 鼠标进入（进入子元素不触发）</p>
<p><a href="http://api.jquery.com/mouseleave/">.mouseleave()</a> 鼠标离开（离开子元素不触发）</p>
<p><a href="http://api.jquery.com/mousemove/">.mousemove()</a> 鼠标在元素内部移动</p>
<p><a href="http://api.jquery.com/mouseleave/">.mouseout()</a> 鼠标离开（离开子元素也触发）</p>
<p><a href="http://api.jquery.com/mouseover/">.mouseover()</a> 鼠标进入（进入子元素也触发）</p>
<p><a href="http://api.jquery.com/mouseup/">.mouseup()</a> 松开鼠标</p>
<p><a href="http://api.jquery.com/ready/">.ready()</a> DOM加载完成</p>
<p><a href="http://api.jquery.com/resize/">.resize()</a> 浏览器窗口的大小发生改变</p>
<p><a href="http://api.jquery.com/scroll/">.scroll()</a> 滚动条的位置发生变化</p>
<p><a href="http://api.jquery.com/select/">.select()</a> 用户选中文本框中的内容</p>
<p><a href="http://api.jquery.com/submit/">.submit()</a> 用户递交表单</p>
<p><a href="http://api.jquery.com/toggle-event/">.toggle()</a> 根据鼠标点击的次数，依次运行多个函数</p>
<p><a href="http://api.jquery.com/unload/">.unload()</a> 用户离开页面</p></blockquote>
<p>以上这些事件在jQuery内部，都是<a href="http://api.jquery.com/bind/">.bind()</a>的便捷方式。使用<a href="http://api.jquery.com/bind/">.bind()</a>可以更灵活地控制事件，比如为多个事件绑定同一个函数：</p>
<blockquote><p>　　$(&#8216;input&#8217;).bind(</p>
<p>&#8216;click change&#8217;, //同时绑定click和change事件</p>
<p>function() {</p>
<p>alert(&#8216;Hello&#8217;);</p>
<p>}</p>
<p>);</p></blockquote>
<p>有时，你只想让事件运行一次，这时可以使用<a href="http://api.jquery.com/one/">.one()</a>方法。</p>
<blockquote><p>　　$(“p”).one(“click”, function() {</p>
<p>alert(“Hello”); //只运行一次，以后的点击不会运行</p>
<p>});</p></blockquote>
<p><a href="http://api.jquery.com/unbind/">.unbind()</a>用来解除事件绑定。</p>
<blockquote><p>　　$(&#8216;p&#8217;).unbind(&#8216;click&#8217;);</p></blockquote>
<p>所有的事件处理函数，都可以接受一个<a href="http://api.jquery.com/category/events/event-object/">事件对象</a>（event object）作为参数，比如下面例子中的e：</p>
<blockquote><p>　　$(“p”).click(function(e) {</p>
<p>alert(e.type); // “click”</p>
<p>});</p></blockquote>
<p>这个事件对象有一些很有用的属性和方法：</p>
<blockquote><p>　　<a href="http://api.jquery.com/event.pageX/">event.pageX</a> 事件发生时，鼠标距离网页左上角的水平距离</p>
<p><a href="http://api.jquery.com/event.pageY/">event.pageY</a> 事件发生时，鼠标距离网页左上角的垂直距离</p>
<p><a href="http://api.jquery.com/event.type/">event.type</a> 事件的类型（比如click）</p>
<p><a href="http://api.jquery.com/event.which/">event.which</a> 按下了哪一个键</p>
<p><a href="http://api.jquery.com/event.data/">event.data</a> 在事件对象上绑定数据，然后传入事件处理函数</p>
<p><a href="http://api.jquery.com/event.target/">event.target</a> 事件针对的网页元素</p>
<p><a href="http://api.jquery.com/event.preventDefault/">event.preventDefault()</a> 阻止事件的默认行为（比如点击链接，会自动打开新页面）</p>
<p><a href="http://api.jquery.com/event.stopPropagation/">event.stopPropagation()</a> 停止事件向上层元素冒泡</p></blockquote>
<p>在事件处理函数中，可以用this关键字，返回事件针对的DOM元素：</p>
<blockquote><p>　　$(&#8216;a&#8217;).click(function() {</p>
<p>if ($(this).attr(&#8216;href&#8217;).match(&#8216;evil&#8217;)) { //如果确认为有害链接</p>
<p>e.preventDefault(); //阻止打开</p>
<p>$(this).addClass(&#8216;evil&#8217;); //加上表示有害的class</p>
<p>}</p>
<p>});</p></blockquote>
<p>有两种方法，可以自动触发一个事件。一种是直接使用事件函数，另一种是使用<a href="http://api.jquery.com/trigger/">.trigger()</a>或<a href="http://api.jquery.com/triggerHandler/">.triggerHandler()</a>。</p>
<blockquote><p>　　$(&#8216;a&#8217;).click();</p>
<p>$(&#8216;a&#8217;).trigger(&#8216;click&#8217;);</p></blockquote>
<p><strong>九、特殊效果</strong></p>
<p>jQuery允许对象呈现某些<a href="http://api.jquery.com/category/effects/">特殊效果</a>。</p>
<blockquote><p>　　$(&#8216;h1&#8242;).show(); //展现一个h1标题</p></blockquote>
<p>常用的特殊效果如下：</p>
<blockquote><p>　　<a href="http://api.jquery.com/fadeIn/">.fadeIn()</a> 淡入</p>
<p><a href="http://api.jquery.com/fadeOut/">.fadeOut()</a> 淡出</p>
<p><a href="http://api.jquery.com/fadeTo/">.fadeTo()</a> 调整透明度</p>
<p><a href="http://api.jquery.com/hide/">.hide()</a> 隐藏元素</p>
<p><a href="http://api.jquery.com/show/">.show()</a> 显示元素</p>
<p><a href="http://api.jquery.com/slideDown/">.slideDown()</a> 向下展开</p>
<p><a href="http://api.jquery.com/slideUp/">.slideUp()</a> 向上卷起</p>
<p><a href="http://api.jquery.com/slideToggle/">.slideToggle()</a> 依次展开或卷起某个元素</p>
<p><a href="http://api.jquery.com/toggle/">.toggle()</a> 依次展示或隐藏某个元素</p></blockquote>
<p>除了<a href="http://api.jquery.com/show/">.show()</a>和<a href="http://api.jquery.com/hide/">.hide()</a>，所有其他特效的默认执行时间都是400ms（毫秒），但是你可以改变这个设置。</p>
<blockquote><p>　　$(&#8216;h1&#8242;).fadeIn(300); // 300毫秒内淡入</p>
<p>$(&#8216;h1&#8242;).fadeOut(&#8216;slow&#8217;); // 缓慢地淡出</p></blockquote>
<p>在特效结束后，可以指定执行某个函数。</p>
<blockquote><p>　　$(&#8216;p&#8217;).fadeOut(300, function() { $(this).remove(); });</p></blockquote>
<p>更复杂的特效，可以用<a href="http://api.jquery.com/animate/">.animate()</a>自定义。</p>
<blockquote><p>　　$(&#8216;div&#8217;).animate(</p>
<p>{</p>
<p>left : “+=50&#8243;, //不断右移</p>
<p>opacity : 0.25 //指定透明度</p>
<p>},</p>
<p>300, // 持续时间</p>
<p>function() { alert(&#8216;done!&#8217;); } //回调函数</p>
<p>);</p></blockquote>
<p><a href="http://api.jquery.com/stop/">.stop()</a>和<a href="http://api.jquery.com/delay/">.delay()</a>用来停止或延缓特效的执行。</p>
<p><a href="http://api.jquery.com/jQuery.fx.off/">$.fx.off</a>如果设置为true，则关闭所有网页特效。</p>
<p>（完）</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhblog.net/archives/899.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python 编码风格指南中译版</title>
		<link>http://www.zhblog.net/archives/895.html</link>
		<comments>http://www.zhblog.net/archives/895.html#comments</comments>
		<pubDate>Wed, 20 Jul 2011 03:00:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[编程其他]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.zhblog.net/?p=895</guid>
		<description><![CDATA[(重定向自 Develop.PythonStyleGuide) On this page&#8230; (hide) 1.  概述 1.1  Python 语言方面的准则 1.2  Python 编码风格方面的准则 2.  Python 语言方面的准则 2.1  pychecker 2.2  导入模块和包 2.3  完整路径导入 2.4  异常处理 2.5  全局变量 2.6  内嵌/本地/内部类和函数 2.7  List Comprehensions 2.8  默认迭代器和运算符 2.9  生成器 2.10  使用 apply filter map reduce 2.11  Lambda functions 2.12  默认参数值 2.13  Properties 2.14  布尔内置类型 2.15  String 方法 2.16  [...]]]></description>
			<content:encoded><![CDATA[<p><em>(重定向自 <a href="http://www.elias.cn/Develop/PythonStyleGuide?action=edit" rel="nofollow">Develop.PythonStyleGuide</a>)</em></p>
<div class="tocfloat" style="margin-top: 0px;">
<p style="margin-top: 0px;"><a id="toc" name="toc"></a><strong>On this page&#8230;</strong> (<a id="tocidtog" href="javascript:toggle('tocid');">hide</a>)</p>
<ol id="tocid" class="toc" style="margin-top: 0px;">
<li style="margin-top: 0px;">1. <a href="#toc1"> 概述</a>
<ol class="toc" style="margin-top: 0px;">
<li style="margin-top: 0px;">1.1 <a href="#toc2"> Python 语言方面的准则</a></li>
<li style="margin-top: 0px;">1.2 <a href="#toc3"> Python 编码风格方面的准则</a></li>
</ol>
</li>
<li style="margin-top: 0px;">2. <a href="#toc4"> Python 语言方面的准则</a>
<ol class="toc" style="margin-top: 0px;">
<li style="margin-top: 0px;">2.1 <a href="#toc5"> pychecker</a></li>
<li style="margin-top: 0px;">2.2 <a href="#toc6"> 导入模块和包</a></li>
<li style="margin-top: 0px;">2.3 <a href="#toc7"> 完整路径导入</a></li>
<li style="margin-top: 0px;">2.4 <a href="#toc8"> 异常处理</a></li>
<li style="margin-top: 0px;">2.5 <a href="#toc9"> 全局变量</a></li>
<li style="margin-top: 0px;">2.6 <a href="#toc10"> 内嵌/本地/内部类和函数</a></li>
<li style="margin-top: 0px;">2.7 <a href="#toc11"> List Comprehensions</a></li>
<li style="margin-top: 0px;">2.8 <a href="#toc12"> 默认迭代器和运算符</a></li>
<li style="margin-top: 0px;">2.9 <a href="#toc13"> 生成器</a></li>
<li style="margin-top: 0px;">2.10 <a href="#toc14"> 使用 apply filter map reduce</a></li>
<li style="margin-top: 0px;">2.11 <a href="#toc15"> Lambda functions</a></li>
<li style="margin-top: 0px;">2.12 <a href="#toc16"> 默认参数值</a></li>
<li style="margin-top: 0px;">2.13 <a href="#toc17"> Properties</a></li>
<li style="margin-top: 0px;">2.14 <a href="#toc18"> 布尔内置类型</a></li>
<li style="margin-top: 0px;">2.15 <a href="#toc19"> String 方法</a></li>
<li style="margin-top: 0px;">2.16 <a href="#toc20"> 静态域</a></li>
<li style="margin-top: 0px;">2.17 <a href="#toc21"> 函数和方法修饰符</a></li>
<li style="margin-top: 0px;">2.18 <a href="#toc22"> 线程</a></li>
<li style="margin-top: 0px;">2.19 <a href="#toc23"> 高级特性</a></li>
</ol>
</li>
<li style="margin-top: 0px;">3. <a href="#toc24"> Python 编码风格方面的准则</a>
<ol class="toc" style="margin-top: 0px;">
<li style="margin-top: 0px;">3.1 <a href="#toc25"> 分号</a></li>
<li style="margin-top: 0px;">3.2 <a href="#toc26"> 每行长度</a></li>
<li style="margin-top: 0px;">3.3 <a href="#toc27"> 圆括号</a></li>
<li style="margin-top: 0px;">3.4 <a href="#toc28"> 缩进</a></li>
<li style="margin-top: 0px;">3.5 <a href="#toc29"> 空行</a></li>
<li style="margin-top: 0px;">3.6 <a href="#toc30"> 空格</a></li>
<li style="margin-top: 0px;">3.7 <a href="#toc31"> Python 解释器</a></li>
<li style="margin-top: 0px;">3.8 <a href="#toc32"> 注释</a></li>
<li style="margin-top: 0px;">3.9 <a href="#toc33"> 类</a></li>
<li style="margin-top: 0px;">3.10 <a href="#toc34"> 字符串</a></li>
<li style="margin-top: 0px;">3.11 <a href="#toc35"> TODO style</a></li>
<li style="margin-top: 0px;">3.12 <a href="#toc36"> import 分组及顺序</a></li>
<li style="margin-top: 0px;">3.13 <a href="#toc37"> 语句</a></li>
<li style="margin-top: 0px;">3.14 <a href="#toc38"> 访问控制</a></li>
<li style="margin-top: 0px;">3.15 <a href="#toc39"> 命名</a></li>
<li style="margin-top: 0px;">3.16 <a href="#toc40"> 程序入口</a></li>
<li style="margin-top: 0px;">3.17 <a href="#toc41"> 总结</a></li>
</ol>
</li>
</ol>
</div>
<p class="vspace">针对<a class="urllink" href="http://code.google.com/p/soc/wiki/PythonStyleGuide" rel="nofollow">Python Style Guide</a> Jun 18, 2009 版本翻译<span id="more-895"></span></p>
<ul>
<li>译文发布于：<a class="urllink" href="http://www.elias.cn/Develop/PythonStyleGuide" rel="nofollow">http://www.elias.cn/Develop/PythonStyleGuide</a></li>
<li>译者：elias DOT soong AT gmail DOT com</li>
</ul>
<p class="vspace">本文是向 Melange 项目贡献 <a href="http://www.zhblog.net/archives/tag/python" class="st_tag internal_tag" rel="tag" title="标签 python 下的日志">Python</a> 代码的编码风格指南。</p>
<p class="vspace"><a class="urllink" href="http://code.google.com/p/soc/wiki/SoCOverview" rel="nofollow">SoC framework</a>项目以及在此之上构建的<a class="urllink" href="http://code.google.com/p/soc/wiki/MelangeIntro" rel="nofollow">Melange web applications</a>都是用 Python 语言实现的（因为 Python 是<a class="urllink" href="http://code.google.com/appengine/" rel="nofollow">Google App Engine</a>目前支持的唯一一种编程语言）。本编码风格指南是向 Melange 项目贡献 Python 代码的“要做”和“不要做”的列表。</p>
<p class="vspace">下面这些规则不是原则或建议，而是严格的规定。你不能不理会这些规定除非是确实需要使用并被允许了，但仍然要注意本指南结尾处<a href="#Conclusion">一致性</a>部分的建议。</p>
<p class="vspace">如果你有关于这些准则的问题，可以向<a class="urllink" href="http://code.google.com/p/soc/wiki/MailingListsGuidelines#Developer_list" rel="nofollow">开发者邮件列表</a>发邮件询问。请在邮件标题写上“<span style="color: red; font-size: 120%; font-weight: bold;">Python style:</span>”，以便在邮件列表归档中更容易定位这些讨论。</p>
<p class="vspace">本编码风格指南写在 Melange 项目的 Wiki 上，可以遵循已有的<a class="createlinktext" href="http://www.elias.cn/Python/DocumentationReviews?action=edit" rel="nofollow">文档复查流程</a><a class="createlink" href="http://www.elias.cn/Python/DocumentationReviews?action=edit" rel="nofollow">?</a>进行修改。但不应该轻易修改本文，因为<a href="#Conclusion">一致性</a>是本指南的一个关键目标，而且不能因为新的风格指南变化而需要更新旧代码。</p>
<h1 style="margin-top: 0px;"><a id="toc1" name="toc1"></a>1.  概述</h1>
<h2 style="margin-top: 0px;"><a id="toc2" name="toc2"></a>1.1  Python 语言方面的准则</h2>
<ol>
<li><a href="#pychecker">pychecker</a>: 建议使用</li>
<li><a href="#Module_and_package_imports">导入模块和包</a>: 可以，<span style="color: red; font-size: 120%; font-weight: bold;">但不要 import * </span></li>
<li><a href="#Packages">完整路径导入</a>: 可以</li>
<li><a href="#Exceptions">异常处理</a>: 可以</li>
<li><a href="#Global_variables">全局变量</a>: 谨慎使用</li>
<li><a href="#Nested_Local_Inner_Classes_and_Functions">内嵌/本地/内部类和函数</a>: 可以</li>
<li><a href="#List_Comprehensions">List Comprehensions</a>: 可以用，如果<span style="color: red; font-size: 120%; font-weight: bold;">简明易懂</span>的话</li>
<li><a href="#Default_Iterators_and_Operators">默认迭代器和运算符</a>: 可以</li>
<li><a href="#Generators">生成器</a>: 可以</li>
<li><a href="#Using_apply_filter_map_reduce">使用 apply、 filter、 map、 reduce</a>: 对<span style="color: red; font-size: 120%; font-weight: bold;">one-liner</span>来说可以</li>
<li><a href="#Lambda_functions">Lambda 函数</a>: 对<span style="color: red; font-size: 120%; font-weight: bold;">one-liner</span>来说可以</li>
<li><a href="#Default_Argument_Values">默认参数值</a>: 可以</li>
<li><a href="#Properties">Properties</a>: 可以</li>
<li><a href="#True_False_evaluations">True/False 求值</a>: 可以</li>
<li><a href="#Boolean_built_in_type">布尔内置类型</a>: 可以</li>
<li><a href="#String_Methods">String 方法</a>: 可以</li>
<li><a href="#Lexical_Scoping">静态域</a>: 可以</li>
<li><a href="#Function_and_Method_Decorators">函数和方法修饰符</a>: <span style="color: red; font-size: 120%; font-weight: bold;">适度</span>使用</li>
<li><a href="#Threading">线程</a>: <span style="color: red; font-size: 120%; font-weight: bold;">不要用</span>（<a class="urllink" href="http://code.google.com/appengine/kb/general.html#libraries" rel="nofollow">Google App Engine</a>不支持）</li>
<li><a href="#Power_features">高级特性</a>: <span style="color: red; font-size: 120%; font-weight: bold;">不要用</span></li>
</ol>
<h2 style="margin-top: 0px;"><a id="toc3" name="toc3"></a>1.2  Python 编码风格方面的准则</h2>
<p>所有文件都保持一致风格时程序要容易维护得多，以下是 Melange 项目的标准 Python 编码风格规范：</p>
<ol>
<li><a href="#Semicolons">分号</a>: <span style="color: red; font-size: 120%; font-weight: bold;">避免使用</span></li>
<li><a href="#Line_length">每行长度</a>: 最多<span style="color: red; font-size: 120%; font-weight: bold;">80</span>列</li>
<li><a href="#Parentheses">圆括号</a>: <span style="color: red; font-size: 120%; font-weight: bold;">吝啬地用</span></li>
<li><a href="#Indentation">缩进</a>: <span style="color: red; font-size: 120%; font-weight: bold;">2</span> 空格（<span style="color: red; font-size: 120%; font-weight: bold;">不要用 tab </span>），<span style="color: red; font-size: 120%; font-weight: bold;">和<a class="urllink" style="color: red;" href="http://www.python.org/dev/peps/pep-0008/" rel="nofollow">PEP8</a>有所区别</span></li>
<li><a href="#Blank_lines">空行</a>: 对函数和类用 <span style="color: red; font-size: 120%; font-weight: bold;">2</span> 个空行分隔，对类的方法用 <span style="color: red; font-size: 120%; font-weight: bold;">1</span> 个空行</li>
<li><a href="#Whitespace">空格</a>: 在行内吝啬地使用</li>
<li><a href="#Python_Interpreter">Python 解释器</a>: 用<a class="urllink" href="http://code.google.com/appengine/docs/python/purepython.html" rel="nofollow">Google App Engine</a>支持的那个： <span style="color: blue;">#!/usr/bin/python2.5</span></li>
<li><a href="#Comments">注释</a>: <span style="color: blue;">__doc__</span>strings、块注释、行内注释
<ul>
<li><a href="#Doc_strings">__doc__ Strings</a></li>
<li><a href="#Modules">模块</a></li>
<li><a href="#Functions_and_Methods">函数和方法</a></li>
<li><a href="#Classes">类</a></li>
<li><a href="#Block_and_Inline_Comments">块注释及行内注释</a></li>
</ul>
</li>
<li><a href="#Classes">类</a>: 继承 object</li>
<li><a href="#Strings">字符串</a>: 避免重复使用 <span style="color: blue;">+</span> 和 <span style="color: blue;">+=</span></li>
<li><a href="#TODO_style">TODO style</a>: <span style="color: blue;">TODO(username):</span> 使用一种一致的风格</li>
<li><a href="#Imports_grouping_and_order">import 分组、排序和整理</a>: 一行一个，按包名字分组顺序放置，按字母顺序排序</li>
<li><a href="#Statements">语句</a>: 一行一个，避免使用<a href="#Semicolons">分号</a></li>
<li><a href="#Access_control">访问控制</a>: 轻量化风格可以用 <span style="color: blue;">foo</span>，否则用 <span style="color: blue;"><span class="wikiword">GetFoo</span>()</span> 和 <span style="color: blue;"><span class="wikiword">SetFoo</span>()</span></li>
<li><a href="#Naming">命名</a>: 用 <span style="color: blue;">foo_bar.py</span> 而不是 <span style="color: blue;">foo-bar.py</span>，和<span style="color: red; font-size: 120%; font-weight: bold;"><a class="urllink" style="color: red;" href="http://www.python.org/dev/peps/pep-0008/" rel="nofollow">PEP8</a>有些区别</span></li>
<li><a href="#Main">程序入口</a>: <span style="color: blue;">if __name__ == &#8216;__main__&#8217;:</span></li>
<li><a href="#Conclusion">总结</a>: 看看你周围是什么</li>
</ol>
<h1 style="margin-top: 0px;"><a id="toc4" name="toc4"></a>2.  Python 语言方面的准则</h1>
<h2 style="margin-top: 0px;"><a id="toc5" name="toc5"></a>2.1  pychecker <a id="pychecker" name="pychecker"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> <span style="color: blue;">pychecker</span> 是从 Python 源代码中找 Bug 的工具。类似 lint ，它寻找在 C 和 C++ 那样更少动态化的语言中通常由编译器捕捉的那些问题。因为 Python 天生就是动态化的，其中一些警告可能并不正确；但假警报应该是相当少见的。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 捕捉易犯的错误，比如拼写、在赋值之前就使用变量等等。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> <span style="color: blue;">pychecker</span> 不是完美的。为了好好利用它，我们有时候得：a) 针对它来写代码 b) 禁用特定警告 c) 改进它 d) 或者忽略它。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 确保在代码上执行 <span style="color: blue;">pychecker</span>。</p>
<p class="vspace">你可以设置一个名为 <span style="color: blue;">__pychecker__</span> 的模块级别变量来适当禁用某些警告。比如：</p>
<div id="sourceblock1" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">__pychecker__ = <span class="st0">&#8216;no-callinit no-classattr&#8217;</span></div>
</div>
</div>
<p class="vspace">用这种方法禁用有个好处：我们可以很容易地找到这些禁用并且重新启用它们。</p>
<p class="vspace">你可以用 <span style="color: blue;">pychecker &#8211;help</span> 来获得 <span style="color: blue;">pychecker</span> 警告的列表。</p>
<p class="vspace">禁用“未被使用的变量”警告可以用 <span style="color: blue;">_</span> 作为未使用变量的标识符，或者给变量名添加 <span style="color: blue;">unused_</span> 前缀。有些情况下无法改变变量名，那你可以在函数开头调用它们一下，比如：</p>
<div id="sourceblock2" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">def</span> Foo<span class="br0">(</span>a, unused_b, unused_c, d=<span class="kw2">None</span>, e=<span class="kw2">None</span><span class="br0">)</span>:d, e = <span class="br0">(</span>d, e<span class="br0">)</span>  <span class="co1"># silence pychecker</span></p>
<p><span class="kw1">return</span> a</p>
</div>
</div>
</div>
<p class="vspace">最理想的是， <span style="color: blue;">pychecker</span> 会竭尽全力保证这样的“未使用声明”是真实的。</p>
<p class="vspace">你可以在<a class="urllink" href="http://www.google.com/url?sa=D&amp;q=http://pychecker.sourceforge.net" rel="nofollow">PyChecker 主页</a>找到更多相关信息。</p>
<div class="sectionedit"><a name="sPython.PythonStyleGuide_6"><br />
</a></div>
<h2 style="margin-top: 0px;"><a id="toc6" name="toc6"></a>2.2  导入模块和包 <a id="Module_and_package_imports" name="Module_and_package_imports"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 在模块与模块之间共享代码的重用机制。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 最简单同时也是最常用的共用方法。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> <span style="color: blue;">from foo import *</span> 或者 <span style="color: blue;">from foo import Bar</span> 很恶心而且这会使寻找模块之间的依赖关系变难，从而导致严重的维护问题。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 用 <span style="color: blue;">import x</span> 来导入包和模块。只有在 <span style="color: blue;">x</span> 是一个包（package），而 <span style="color: blue;">y</span> 是一个模块（module）的时候才用 <span style="color: blue;">from x import y</span> 。这可以让使用者无需说明完整的包前缀就能引用模块。比如 <span style="color: blue;">sound.effects.echo</span> 包可以像下面这样导入：</p>
<div id="sourceblock3" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">from</span> sound.<span class="me1">effects</span> <span class="kw1">import</span>echo&#8230;</p>
<p><span class="me1">echo</span>.<span class="me1">echofilter</span><span class="br0">(</span><span class="kw2">input</span>, output, delay=<span class="nu0">0.7</span>, atten=<span class="nu0">4</span><span class="br0">)</span></p>
</div>
</div>
</div>
<p class="vspace">即使模块是在同一个包里，也不要直接导入模块而不给出完整的包名字。这可能导致包被导入多次以及非预期的副作用。</p>
<p class="vspace">例外的情况：<span style="color: red; font-size: 120%; font-weight: bold;">当且仅当</span> Bar 是 foo 中的一个顶级 singleton，并且叫做 foo_Bar 是为了描述 Bar 与 foo 之间的关系，那么才可以用 <span style="color: blue;">from foo import Bar as foo_Bar</span> 。</p>
<p class="vspace">比如，像下面这样是可以的：</p>
<div id="sourceblock4" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">from</span> soc.<span class="me1">logic</span>.<span class="me1">models</span>.<span class="kw3">user</span> <span class="kw1">import</span> logic <span class="kw1">as</span>user_logic&#8230;</p>
<p><span class="me1">user_logic</span>.<span class="me1">getForCurrentAccount</span><span class="br0">(</span><span class="br0">)</span></p>
</div>
</div>
</div>
<p class="vspace">以下写法更受欢迎：</p>
<div id="sourceblock5" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">from</span> soc.<span class="me1">logic</span> <span class="kw1">import</span>models&#8230;</p>
<p><span class="kw1">import</span> soc.<span class="me1">logic</span>.<span class="me1">models</span>.<span class="kw3">user</span></p>
<p>&#8230;</p>
<p><span class="me1">models</span>.<span class="me1">logic</span>.<span class="kw3">user</span>.<span class="me1">logic</span>.<span class="me1">getForCurrentAccount</span><span class="br0">(</span><span class="br0">)</span></p>
</div>
</div>
</div>
<h2 style="margin-top: 0px;"><a id="toc7" name="toc7"></a>2.3  完整路径导入 <a id="Packages" name="Packages"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 每个模块都通过模块的完整路径位置导入和引用。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 避免模块名字之间的冲突，而且查找模块更容易。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 部署代码会麻烦一些，因为你必须重现整个包的分层结构。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 所有新代码都应该使用他们的包名字来引用模块。不要为了从其他目录导入模块而修改 <span style="color: blue;">sys.path</span> 和 <span style="color: blue;">PATHONPATH</span>。（可能有些情况下仍然需要修改路径，但只要可能的话就应该避免这样做。）</p>
<p class="vspace">应该像下面这样导入：</p>
<div id="sourceblock6" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="co1"># 使用完整名字引用：</span><span class="kw1">import</span> soc.<span class="kw3">logging</span><span class="co1"># 仅使用模块名字引用：</span></p>
<p><span class="kw1">from</span> soc <span class="kw1">import</span> <span class="kw3">logging</span></p>
</div>
</div>
</div>
<p class="vspace">有些包名字可能和常用的本地变量名是一样的。在这种情况下为了避免混乱，先导入包然后清晰地单独导入模块有时候也是有意义的。结果看起来像这样：</p>
<div id="sourceblock7" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">from</span> soc <span class="kw1">import</span>models<span class="kw1">import</span> soc.<span class="me1">models</span>.<span class="kw3">user</span>&#8230;</p>
<p><span class="kw3">user</span> = models.<span class="kw3">user</span>.<span class="me1">User</span><span class="br0">(</span><span class="br0">)</span></p>
<p class="vspace">在创建时就避免易引发混乱的模块命名可能是最佳方案，但有时选择直观的模块名字（比如上面例子中 <span style="color: blue;">soc.models</span> 中的那些模块）<span style="color: red; font-size: 120%; font-weight: bold;">会</span>导致需要像上面这样做 workaround 。</p>
<h2 style="margin-top: 0px;"><a id="toc8" name="toc8"></a>2.4  异常处理 <a id="Exceptions" name="Exceptions"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 异常处理指的是为处理错误及其他异常状况而打破代码块的正常控制流。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 正常操作代码的控制流不会被错误处理代码弄乱。也可以在特定情况发生时让控制流跳过多个步骤，比如一步就从 N 层嵌套函数（nested functions）中返回，而不必继续把错误代码一步步执行到底。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 可能使控制流变得难以理解，以及在做函数库调用时容易忽略一些错误情况。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 异常处理是很 Pythonic 的，因此我们当然同意用它，但只是在符合以下特定条件时：</p>
<ul>
<li>要像这样抛出异常：<span style="color: blue;">raise <span class="wikiword">MyException</span>(“Error message”)</span> 或者 <span style="color: blue;">raise <span class="wikiword">MyException</span></span>，而不要用双参数的形式（<span style="color: blue;">raise <span class="wikiword">MyException</span>, “Error message”</span>） 或者 已废弃的基于字符串的异常（<span style="color: blue;">raise “Error message”</span>）。</li>
<li>模块和包应该定义自己的特定领域的基础异常类，而且这个类应该继承自内置的 <span style="color: blue;">Exception</span> 类。这种用于一个模块的基础异常应该命名为 <span style="color: blue;">Error</span>。
<div id="sourceblock8" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">class</span> Error<span class="br0">(</span><span class="kw2">Exception</span><span class="br0">)</span>:</p>
<p><span class="st0">“”"Base exception for all exceptions raised in module Foo.”"”</span></p>
<p><span class="kw1">pass</span></p>
</div>
</div>
</div>
</li>
<li>永远不要直接捕获所有异常，也即 <span style="color: blue;">except:</span> 语句，或者捕获 <span style="color: blue;">Exception</span> 和 <span style="color: blue;"><span class="wikiword">StandardError</span></span>，除非你会把异常重新抛出或者是在你线程最外层的代码块中（而且你会打印一个出错信息）。在这种意义上来讲， Python 是很健壮的，因为 <span style="color: blue;">except:</span> 会真正捕获包括 Python 语法错误在内的所有东西。使用 <span style="color: blue;">except:</span> 很容易会掩盖真正的 Bug 。</li>
<li>在 <span style="color: blue;">try/except</span> 块中使代码量最小化。<span style="color: blue;">try</span> 里头的内容越多，就更有可能出现你原先并未预期会抛出异常的代码抛出异常的情况。在这种情况下，<span style="color: blue;">try/except</span> 代码块就隐藏了真正的错误。</li>
<li>使用 <span style="color: blue;">finally</span> 子句执行一段代码而无论 <span style="color: blue;">try</span> 语句块是否会抛出异常。这在做清除工作的时候经常是很有用的，比如关闭文件。</li>
</ul>
<h2 style="margin-top: 0px;"><a id="toc9" name="toc9"></a>2.5  全局变量 <a id="Global_variables" name="Global_variables"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 在模块级别声明的变量。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 有时很有用。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 有可能在导入时改变模块的行为，因为在模块被导入时完成了模块级别变量的赋值。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 推荐使用类变量而避免使用全局变量。以下是一些例外情况：</p>
<ul>
<li>作为脚本中的默认选项。</li>
<li>模块级别常量，例如 <span style="color: blue;">PI = 3.14159</span> 。常量名应该全部使用大写字母并用下划线分隔，参考下文<a href="#Naming">命名</a>章节。</li>
<li>有时全局变量对缓存函数返回值或其他需要的运算结果会是挺有用的。</li>
<li>在需要的时候，全局变量应该被用作模块的内部变量，并通过公开的模块级函数来访问。参考下文<a class="createlinktext" href="http://www.elias.cn/Python/Naming?action=edit" rel="nofollow">命名</a><a class="createlink" href="http://www.elias.cn/Python/Naming?action=edit" rel="nofollow">?</a>章节。</li>
</ul>
<h2 style="margin-top: 0px;"><a id="toc10" name="toc10"></a>2.6  内嵌/本地/内部类和函数 <a id="Nested_Local_Inner_Classes_and_Functions" name="Nested_Local_Inner_Classes_and_Functions"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 类可以定义在函数或另一个类的内部。函数可以定义在另一个函数的内部。内嵌函数可以只读访问定义在外部作用域中的变量。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 允许定义只用于一个非常有限的作用域内部的工具类和工具函数，实在太方便了（ADT-y）。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 内嵌的本地类实例无法被序列化导出（pickle）。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 挺好的，用吧。</p>
<h2 style="margin-top: 0px;"><a id="toc11" name="toc11"></a>2.7  List Comprehensions <a id="List_Comprehensions" name="List_Comprehensions"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> List Comprehension 和 Generator Expression 提供了一种简明高效的方法来创建列表和迭代器而无需借助 <span style="color: blue;">map()</span> 、 <span style="color: blue;">filter()</span> 、或者 <span style="color: blue;">lambda</span> 。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 简单的 List Comprehensions 比其他列表创建技术更清晰、更简单。Generator Expressions 非常高效，因为它避免了一下子创建整个列表。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 复杂的 List Comprehensions 或 Generator Expressions 很难读懂。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 对一行风格（one-liner）来说没问题，或者在 <span style="color: blue;">x for y in z</span> 能写在一行里而条件语句可以写成另一行的时候（注意下面 <span style="color: blue;">x</span> 很长的、写成三行的那个例子是可以接受的）也可以用。当问题变得更复杂时应该用循环来代替。这是一种主观判断。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No:</span></p>
<div id="sourceblock9" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="co1"># 太复杂了，应该用循环嵌套代替：</span></p>
<p>result = <span class="br0">[</span><span class="br0">(</span>x, y<span class="br0">)</span> <span class="kw1">for</span> x <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">(</span><span class="nu0">10</span><span class="br0">)</span></p>
<p><span class="kw1">for</span> y <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">(</span><span class="nu0">5</span><span class="br0">)</span></p>
<p><span class="kw1">if</span> x <span class="sy0">*</span> y <span class="sy0">&gt;</span> <span class="nu0">10</span><span class="br0">]</span></p>
</div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes:</span></p>
<div id="sourceblock10" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="co1"># 这个例子足够复杂了，*不应该*使用List Comprehension：</span></p>
<p>result = <span class="br0">[</span><span class="br0">]</span></p>
<p><span class="kw1">for</span> x <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">(</span><span class="nu0">10</span><span class="br0">)</span>:</p>
<p><span class="kw1">for</span> y <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">(</span><span class="nu0">5</span><span class="br0">)</span>:</p>
<p><span class="kw1">if</span> x <span class="sy0">*</span> y <span class="sy0">&gt;</span> <span class="nu0">10</span>:</p>
<p>result.<span class="me1">append</span><span class="br0">(</span><span class="br0">(</span>x, y<span class="br0">)</span><span class="br0">)</span></p>
</div>
</div>
</div>
<p><span class="co1"># 简单舒服的一行风格：</span></p>
<p>squares = <span class="br0">[</span>x <span class="sy0">*</span> x <span class="kw1">for</span> x <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">(</span><span class="nu0">10</span><span class="br0">)</span><span class="br0">]</span></p>
<p><span class="co1"># 写成两行的 Generator （不是 List Comprehension）例子，也是可以的：</span></p>
<p>Eat<span class="br0">(</span>jelly_bean <span class="kw1">for</span> jelly_bean <span class="kw1">in</span> jelly_beans</p>
<p><span class="kw1">if</span> jelly_bean.<span class="me1">color</span> == <span class="st0">&#8216;black&#8217;</span><span class="br0">)</span></p>
<p><span class="co1"># 写成三行的这个例子是否仍然比等价的循环具有更好的可读性还存在争议：</span></p>
<p>result = <span class="br0">[</span>someReallyLongWayToEatAJellyBean<span class="br0">(</span>jelly_bean<span class="br0">)</span></p>
<p><span class="kw1">for</span> jelly_bean <span class="kw1">in</span> jelly_beans</p>
<p><span class="kw1">if</span> jelly_bean <span class="sy0">!</span>= <span class="st0">'black'</span><span class="br0">]</span></p>
<h2 style="margin-top: 0px;"><a id="toc12" name="toc12"></a>2.8  默认迭代器和运算符 <a id="Default_Iterators_and_Operators" name="Default_Iterators_and_Operators"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 容器类型（比如字典和列表）定义了默认迭代器和从属关系测试运算符（例如 <span style="color: blue;">in</span> 和 <span style="color: blue;">not in</span>）。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 默认迭代器和运算符又简单又高效，它们无需额外方法调用就能直接表达操作。使用默认运算符来编写函数是一种通用性较强的做法，因为它可以用于任何支持这些操作的数据类型。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 你无法通过阅读方法名字就说出对象的类型（比如说 <span style="color: blue;">has_key()</span> 表示一个字典）。这同时也是一个优点。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 在支持它们的类型上使用默认迭代器和运算符，比如列表、字典、和文件。当然这些内置类型同时也定义了迭代器方法。对返回列表的方法倾向于使用迭代器方法，但你不应该在迭代的过程中修改容器中的内容。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes:</span></p>
<div id="sourceblock11" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">for</span> key <span class="kw1">in</span> adict: &#8230;</p>
<p><span class="kw1">if</span> key <span class="kw1">not</span> <span class="kw1">in</span> adict: &#8230;</p>
<p><span class="kw1">if</span> obj <span class="kw1">in</span> alist: &#8230;</p>
<p><span class="kw1">for</span> line <span class="kw1">in</span> afile: &#8230;</p>
<p><span class="kw1">for</span> k, v <span class="kw1">in</span> <span class="kw2">dict</span>.<span class="me1">iteritems</span><span class="br0">(</span><span class="br0">)</span>: &#8230;</p>
</div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No:</span></p>
<div id="sourceblock12" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">for</span> key <span class="kw1">in</span> adict.<span class="me1">keys</span><span class="br0">(</span><span class="br0">)</span>: &#8230;</p>
<p><span class="kw1">if</span> <span class="kw1">not</span> adict.<span class="me1">has_key</span><span class="br0">(</span>key<span class="br0">)</span>: &#8230;</p>
<p><span class="kw1">for</span> line <span class="kw1">in</span> afile.<span class="me1">readlines</span><span class="br0">(</span><span class="br0">)</span>: &#8230;</p>
</div>
</div>
</div>
<h2 style="margin-top: 0px;"><a id="toc13" name="toc13"></a>2.9  生成器 <a id="Generators" name="Generators"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 生成器函数返回一个迭代器，而这个迭代器每次执行 <span style="color: blue;">yield</span> 语句生成一个计算结果。每次生成一个计算结果之后，生成器函数的运行时状态被挂起，直到需要生成下一个计算结果时。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 代码更简单。因为对每次调用来说，本地变量和控制流的状态都是被保留的。生成器比用计算结果一次性填满整个列表的函数更节省内存。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 没有。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 很好。在生成器函数的 <span style="color: blue;">__doc__</span> String 中使用 <span style="color: blue;">“Yields:”</span> 而不是 <span style="color: blue;">“Returns:”</span> 。</p>
<h2 style="margin-top: 0px;"><a id="toc14" name="toc14"></a>2.10  使用 apply filter map reduce <a id="Using_apply_filter_map_reduce" name="Using_apply_filter_map_reduce"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 实用的内置列表操作函数。通常和 <span style="color: blue;">lambda</span> 函数一起用。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 代码很紧凑。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 高阶函数式编程恐怕更难理解。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 对简单代码和喜欢把代码写成一行的人来说，尽可能用 List Comprehension 而限制使用这些内置函数。一般来说，如果代码在任何地方长度超过60到80个字符，或者使用了多层函数调用（例如，<span style="color: blue;">map(lambda x: x[1], filter(&#8230;)))</span>），那这就是一个信号提醒你最好把它重新写成一个普通的循环。比较：</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">map/filter:</span></p>
<div id="sourceblock13" class="sourceblock ">
<div class="sourceblocktext">
<div class="python"><span class="kw2">map</span><span class="br0">(</span><span class="kw1">lambda</span> x:x<span class="br0">[</span><span class="nu0">1</span><span class="br0">]</span>, <span class="kw2">filter</span><span class="br0">(</span><span class="kw1">lambda</span> x:x<span class="br0">[</span><span class="nu0">2</span><span class="br0">]</span> == <span class="nu0">5</span>, my_list<span class="br0">)</span><span class="br0">)</span></div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">list comprehensions:</span></p>
<div id="sourceblock14" class="sourceblock ">
<div class="sourceblocktext">
<div class="python"><span class="br0">[</span>x<span class="br0">[</span><span class="nu0">1</span><span class="br0">]</span> <span class="kw1">for</span> x <span class="kw1">in</span> my_list <span class="kw1">if</span> x<span class="br0">[</span><span class="nu0">2</span><span class="br0">]</span> == <span class="nu0">5</span><span class="br0">]</span></div>
</div>
</div>
<h2 style="margin-top: 0px;"><a id="toc15" name="toc15"></a>2.11  Lambda functions <a id="Lambda_functions" name="Lambda_functions"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> Lambda 定义仅包含表达式、没有其他语句的匿名函数，通常用于定义回调或者用于 <span style="color: blue;">map()</span> 和 <span style="color: blue;">filter()</span> 这样高阶函数的运算符。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 方便。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 比本地函数更难阅读和调试。没有名字意味着堆栈追踪信息更难理解。而且函数只能包含一个表达式，因而表达能力也比较有限。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 对喜欢把代码写成一行的人来说没什么问题。只要 <span style="color: blue;">lambda</span> 函数中的代码长度超过60到80个字符，那可能把它定义成一个标准（或者嵌套的）函数更合适。</p>
<p class="vspace">对加法这样的普通操作，应该使用 operator 模块中的函数而不是用 <span style="color: blue;">lambda</span> 函数。例如，应该用 <span style="color: blue;">operator.add</span> 而不是 <span style="color: blue;">lambda x, y: x + y</span>。（内置的 <span style="color: blue;">sum()</span> 函数其实比这两者中的任何一个都更合适。）</p>
<h2 style="margin-top: 0px;"><a id="toc16" name="toc16"></a>2.12  默认参数值 <a id="Default_Argument_Values" name="Default_Argument_Values"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 你可以给函数的参数列表中最靠后的几个变量指定取值，比如 <span style="color: blue;">def foo(a, b=0):</span> 。如果只用一个参数来调用 <span style="color: blue;">foo</span> ，<span style="color: blue;">b</span> 将被设置为 <span style="color: blue;">0</span> 。如果用两个参数来调用它， <span style="color: blue;">b</span> 将使用第二个参数的值。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 通常你会大量使用函数的默认值，但<span style="color: red; font-size: 120%; font-weight: bold;">偶尔</span>会需要覆盖这些值。默认参数值允许用一种简单的办法来做到这一点，而不必为偶尔的例外情形定义一大堆函数。而且， Python 不支持方法/函数重载，而参数默认值是“模仿”重载行为的一种简单方法。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 默认参数值会在模块加载的时候被赋值。如果参数是一个列表或者字典之类的可变对象就有可能造成问题。如果函数修改了这个对象（比如在列表最后附加了一个新的项），那默认值也就改变了。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 在以下限制条款下是可以使用的：</p>
<ul>
<li>不要把可变对象当作函数或方法定义的默认值。</li>
</ul>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes:</span></p>
<div id="sourceblock15" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">def</span> foo<span class="br0">(</span>a, b=<span class="kw2">None</span><span class="br0">)</span>:</p>
<p><span class="kw1">if</span> b <span class="kw1">is</span> <span class="kw2">None</span>:</p>
<p>b = <span class="br0">[</span><span class="br0">]</span></p>
</div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No:</span></p>
<div id="sourceblock16" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">def</span> foo<span class="br0">(</span>a, b=<span class="br0">[</span><span class="br0">]</span><span class="br0">)</span>:</p>
<p>&#8230;</p>
</div>
</div>
</div>
<p class="vspace">调用函数的代码必须对默认参数使用指名赋值（named value）。这多少可以帮助代码的文档化，并且当增加新参数进来时帮助避免和发现破坏原有接口。</p>
<div id="sourceblock17" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">def</span> foo<span class="br0">(</span>a, b=<span class="nu0">1</span><span class="br0">)</span>:</p>
<p>&#8230;</p>
</div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes:</span></p>
<div id="sourceblock18" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p>foo<span class="br0">(</span><span class="nu0">1</span><span class="br0">)</span></p>
<p>foo<span class="br0">(</span><span class="nu0">1</span>, b=<span class="nu0">2</span><span class="br0">)</span></p>
</div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No:</span></p>
<div id="sourceblock19" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">foo<span class="br0">(</span><span class="nu0">1</span>, <span class="nu0">2</span><span class="br0">)</span></div>
</div>
<div class="sourceblocklink"></div>
</div>
<h2 style="margin-top: 0px;"><a id="toc17" name="toc17"></a>2.13  Properties <a id="Properties" name="Properties"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 在运算量很小时，把对属性的 get 和 set 方法调用封装为标准的属性访问方式的一个方法。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 对简单的属性访问来说，去掉直率的 <span style="color: blue;">get</span> 和 <span style="color: blue;">set</span> 方法调用提高了代码的可读性。允许延后计算。考虑到 Pythonic 的方法来维护类的接口。在性能方面，当直接变量访问是合理的，允许 Properties 就省略了琐碎的属性访问方法，而且将来仍然可以在不破坏接口的情况下重新加入属性访问方法。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> Properties 在 getter 和 setter 方法声明之后生效，也就是要求使用者注意这些方法在代码很靠后的地方才能被使用（除了用 <span style="color: blue;">@property</span> 描述符创建的只读属性之外 —— 见下文详述）。必须继承自 object 。会像运算符重载一样隐藏副作用。对子类来说会很难理解。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 在那些你通常本来会用简单、轻量的访问/设置方法的代码中使用 Properties 来访问和设置数据。只读的属性应该用 <span style="color: blue;">@property</span> <a class="createlinktext" href="http://www.elias.cn/Python/FunctionAndMethodDecorators?action=edit" rel="nofollow">描述符</a><a class="createlink" href="http://www.elias.cn/Python/FunctionAndMethodDecorators?action=edit" rel="nofollow">?</a>来创建。</p>
<p class="vspace">如果 Property 自身没有被覆盖，那 Properties 的继承并非显而易见。因此使用者必须确保访问方法被间接调用，以便确保子类中被覆盖了的方法会被 Property 调用（使用“模板方法（Template Method）”设计模式）。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes:</span></p>
<div id="sourceblock20" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">import</span> <span class="kw3">math</span></p>
<p><span class="kw1">class</span> Square<span class="br0">(</span><span class="kw2">object</span><span class="br0">)</span>:</p>
<p><span class="st0">“”"基类 square 有可写的 &#8216;area&#8217; 属性和只读的 &#8216;perimeter&#8217; 属性。</span></p>
<p>可以这样使用：</p>
<p>&gt;&gt;&gt; sq = Square(3)</p>
<p>&gt;&gt;&gt; sq.area</p>
<p>9</p>
<p>&gt;&gt;&gt; sq.perimeter</p>
<p>12</p>
<p>&gt;&gt;&gt; sq.area = 16</p>
<p>&gt;&gt;&gt; sq.side</p>
<p>4</p>
<p>&gt;&gt;&gt; sq.perimeter</p>
<p>16</p>
<p>“”"</p>
<p><span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">(</span><span class="kw2">self</span>, side<span class="br0">)</span>:</p>
<p><span class="kw2">self</span>.<span class="me1">side</span> = side</p>
<p><span class="kw1">def</span> _getArea<span class="br0">(</span><span class="kw2">self</span><span class="br0">)</span>:</p>
<p><span class="st0">“”"计算 &#8216;area&#8217; 属性的值”"”</span></p>
<p><span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">side</span> <span class="sy0">**</span> <span class="nu0">2</span></p>
<p><span class="kw1">def</span> __getArea<span class="br0">(</span><span class="kw2">self</span><span class="br0">)</span>:</p>
<p><span class="st0">“”"对 &#8216;area&#8217; 属性的间接访问器”"”</span></p>
<p><span class="kw1">return</span> <span class="kw2">self</span>._getArea<span class="br0">(</span><span class="br0">)</span></p>
<p><span class="kw1">def</span> _setArea<span class="br0">(</span><span class="kw2">self</span>, area<span class="br0">)</span>:</p>
<p><span class="st0">“”"对 &#8216;area&#8217; 属性的设置器”"”</span></p>
<p><span class="kw2">self</span>.<span class="me1">side</span> = <span class="kw3">math</span>.<span class="me1">sqrt</span><span class="br0">(</span>area<span class="br0">)</span></p>
<p><span class="kw1">def</span> __setArea<span class="br0">(</span><span class="kw2">self</span>, area<span class="br0">)</span>:</p>
<p><span class="st0">“”"对 &#8216;area&#8217; 属性的间接设置器”"”</span></p>
<p><span class="kw2">self</span>._setArea<span class="br0">(</span>area<span class="br0">)</span></p>
<p>area = <span class="kw2">property</span><span class="br0">(</span>__getArea, __setArea,</p>
<p>doc=<span class="st0">“”"Get or set the area of the square”"”</span><span class="br0">)</span></p>
<p>@<span class="kw2">property</span></p>
<p><span class="kw1">def</span> perimeter<span class="br0">(</span><span class="kw2">self</span><span class="br0">)</span>:</p>
<p><span class="kw1">return</span> <span class="kw2">self</span>.<span class="me1">side</span> <span class="sy0">*</span> <span class="nu0">4</span></p>
</div>
</div>
</div>
<p class="vspace">== True/False 求值 <a id="True_False_evaluations" name="True_False_evaluations"></a></p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 在布尔型上下文下， Python 把一些特定的取值当作“false”处理。快速的“经验法则”是所有的“空”值都会被认为是“false”，也即 <span style="color: blue;">0</span>、<span style="color: blue;">None</span>、<span style="color: blue;">[]</span>、<span style="color: blue;">{}</span>、<span style="color: blue;">“”</span> 在布尔型上下文中都会被当作“false”。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 使用 Python 的布尔型条件更容易阅读而且更不容易产生错误。在大多数情况下，这也是运行速度更快的选择。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 对 C/C++ 开发者来说可能会看起来很奇怪。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 在所有可能的情况下使用这种“隐含”的 false ，比如用 <span style="color: blue;">if foo:</span> 而不是 <span style="color: blue;">if foo != []:</span> 。这有几条你应该时刻注意的限制条件：</p>
<ul>
<li>与具有唯一性的值比如 <span style="color: blue;">None</span> 进行比较时总是应该使用 <span style="color: blue;">is</span> 或者 <span style="color: blue;">is not</span>。而且，留神在写 <span style="color: blue;">if x:</span> 而你的实际意思是 <span style="color: blue;">if x is not None:</span> 的时候，比如，测试一个默认值是 <span style="color: blue;">None</span> 的变量或参数是否被设置为其他值。这里的“其他值”就有可能是在布尔型上下文中被认为是 false 的值！</li>
<li>对序列（strings、 lists、 tuples）来说，可以利用空序列就是 false 这一事实，也就是说 <span style="color: blue;">if not seq:</span> 或者 <span style="color: blue;">if seq:</span> 比 <span style="color: blue;">if len(seq):</span> 或者 <span style="color: blue;">if not len(seq):</span> 这种形式要更好。</li>
<li>注意 <span style="color: blue;">&#8217;0&#8242;</span> （也即 0 当作字符串）会被求值为 true。</li>
</ul>
<h2 style="margin-top: 0px;"><a id="toc18" name="toc18"></a>2.14  布尔内置类型 <a id="Boolean_built_in_type" name="Boolean_built_in_type"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 从 Python 2.3 开始加入了布尔类型，也即加入了两个新的内置常量：<span style="color: blue;">True</span> 和 <span style="color: blue;">False</span>。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 这使代码更容易阅读而且与之前版本中使用整数作为布尔型的做法向后兼容。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 没有。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 使用布尔型。</p>
<h2 style="margin-top: 0px;"><a id="toc19" name="toc19"></a>2.15  String 方法 <a id="String_Methods" name="String_Methods"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> String 对象包括一些以前是 <span style="color: blue;">string</span> 模块中的函数的方法。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 无需导入 <span style="color: blue;">string</span> 模块，而且这些方法在标准 byte 字符串和 unicode 字符串上都能使用。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 没有。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 用吧。 <span style="color: blue;">string</span> 模块已经被废弃了，现在更推荐使用 String 方法。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No:</span> <span style="color: blue;">words = string.split(foo, &#8216;:&#8217;)</span></p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes:</span> <span style="color: blue;">words = foo.split(&#8216;:&#8217;)</span></p>
<h2 style="margin-top: 0px;"><a id="toc20" name="toc20"></a>2.16  静态域 <a id="Lexical_Scoping" name="Lexical_Scoping"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 被嵌套的 Python 函数（nested Python function）可以引用定义在容器函数（enclosing function）中的变量，但无法对它们重新赋值。变量绑定依据静态域（Lexical Scoping）决定，也就是说，基于静态的程序文本（static program text）。代码块中对一个名字的任意赋值都将导致 Python 把对这个名字的所有引用当作本地变量，即使是先调用后赋值。如果存在全局变量声明，那这个名字就会被当作是全局变量。</p>
<p class="vspace">以下是使用这一特性的例子：</p>
<div id="sourceblock21" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">def</span> getAdder<span class="br0">(</span>summand1<span class="br0">)</span>:</p>
<p><span class="st0">“”"getAdder 返回把数字与一个给定数字相加的函数。”"”</span></p>
<p><span class="kw1">def</span> anAdder<span class="br0">(</span>summand2<span class="br0">)</span>:</p>
<p><span class="kw1">return</span> summand1 + summand2</p>
</div>
</div>
</div>
<p><span class="kw1">return</span>anAdder</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 一般会得到更清晰、更优雅的代码。而且特别符合有经验的 Lisp 和 Scheme （以及 Haskell、ML 等等）程序员的习惯。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 没有。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 可以用。</p>
<h2 style="margin-top: 0px;"><a id="toc21" name="toc21"></a>2.17  函数和方法修饰符 <a id="Function_and_Method_Decorators" name="Function_and_Method_Decorators"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> 在 Python 2.4 版本增加了函数和方法的修饰符（又称“<span style="color: blue;">@</span> notation”）。最常用的修饰符是 <span style="color: blue;">@classmethod</span> 和 <span style="color: blue;">@staticmethod</span>，用于把普通的方法转化为类方法或静态方法。然而，修饰符语法同样允许用户自定义修饰符。具体地，对函数 <span style="color: blue;">myDecorator</span> 来说：</p>
<div id="sourceblock22" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">class</span> C<span class="br0">(</span><span class="kw2">object</span><span class="br0">)</span>:</p>
<p>@myDecorator</p>
<p><span class="kw1">def</span> aMethod<span class="br0">(</span><span class="kw2">self</span><span class="br0">)</span>:</p>
<p><span class="co1"># method body &#8230;</span></p>
</div>
</div>
</div>
<p>和如下代码是等价的：</p>
<div id="sourceblock23" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">class</span> C<span class="br0">(</span><span class="kw2">object</span><span class="br0">)</span>:</p>
<p><span class="kw1">def</span> aMethod<span class="br0">(</span><span class="kw2">self</span><span class="br0">)</span>:</p>
<p><span class="co1"># method body &#8230;</span></p>
<p>aMethod = myDecorator<span class="br0">(</span>aMethod<span class="br0">)</span></p>
</div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 能够优雅地对指定方法进行变形，而且这种变形避免了重复代码，强化了通用性（enforce invariants）等。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 修饰符能对函数的参数和返回值进行任意操作，会导致出乎意料之外的隐含行为。除此之外，修饰符会在导入阶段被执行。修饰符代码中的故障几乎是不可能被修复的。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 在有明显好处时使用修饰符是明智的。修饰符应该和函数遵循同样的导入和命名准则。修饰符的 <span style="color: blue;">__doc__</span> string 应该清晰地声明该函数是一个修饰符，而且要为修饰符写单元测试。</p>
<p class="vspace">避免在修饰符资深引入外部依赖关系（比如，不要依赖文件、 sockets 、数据库连接等），因为在修饰符运行时（在导入阶段，也许源于 <span style="color: blue;">pychecker</span> 或其他工具）这些都有可能是无效的。在所有情况下都应（尽可能）保证使用有效参数调用修饰符时能成功运行。</p>
<p class="vspace">修饰符是“顶级代码”（top level code）的一种特例 —— 参考<a href="#Main">主入口</a>章节的更多讨论。</p>
<h2 style="margin-top: 0px;"><a id="toc22" name="toc22"></a>2.18  线程 <a id="Threading" name="Threading"></a></h2>
<p><a class="urllink" href="http://code.google.com/appengine/kb/general.html#libraries" rel="nofollow">Google App Engine 不支持线程</a>，所以在 <span class="wikiword">SoC</span> framework 和 Melange Web 应用程序中也别用它。</p>
<h2 style="margin-top: 0px;"><a id="toc23" name="toc23"></a>2.19  高级特性 <a id="Power_features" name="Power_features"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">是什么：</span> Python 是一种极为灵活的语言，提供诸如 metaclass、 bytecode 访问、即时编译、动态继承、 object reparenting、 import hacks、反射、修改系统内部结构等很多很炫的特性。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">优点：</span> 这些都是很强大的语言特性，能使你的代码更紧凑。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">缺点：</span> 在并非绝对必要的时候使用这些很“酷”的特性是很诱人的。里面使用了这些并不常见的特性的代码会更难读、更难懂、更难 debug。也许在刚开始的时候好像还没这么糟（对代码的原作者来说），但当你重新回到这些代码，就会觉得这比长点但简单直接的代码要更难搞。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">决定：</span> 在 Melange 代码中避免使用这些特性。例外的情形在<a class="urllink" href="http://code.google.com/p/soc/wiki/MailingListsGuidelines#Developer_list" rel="nofollow">开发者邮件列表</a>中讨论。</p>
<h1 style="margin-top: 0px;"><a id="toc24" name="toc24"></a>3.  Python 编码风格方面的准则</h1>
<h2 style="margin-top: 0px;"><a id="toc25" name="toc25"></a>3.1  分号 <a id="Semicolons" name="Semicolons"></a></h2>
<p>不要用分号作为你的行结束符，也不要利用分号在同一行放两个指令。</p>
<h2 style="margin-top: 0px;"><a id="toc26" name="toc26"></a>3.2  每行长度 <a id="Line_length" name="Line_length"></a></h2>
<p>一行最多可以有80个字符。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">例外：</span> 导入模块的行可以超过80个字符再结束。</p>
<p class="vspace">确保 Python 隐含的连接行（line joining）放在圆括号、方括号或大括号之间。如果需要的话，你可以在表达式两头放一堆额外的圆括号。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span></p>
<div id="sourceblock24" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p>fooBar<span class="br0">(</span><span class="kw2">self</span>, width, height, color=<span class="st0">&#8216;black&#8217;</span>, design=<span class="kw2">None</span>, x=<span class="st0">&#8216;foo&#8217;</span>,</p>
<p>emphasis=<span class="kw2">None</span>, highlight=<span class="nu0">0</span><span class="br0">)</span></p>
</div>
</div>
</div>
<p><span class="kw1">if</span> <span class="br0">(</span><span class="br0">(</span>width == <span class="nu0">0</span><span class="br0">)</span> <span class="kw1">and</span> <span class="br0">(</span>height == <span class="nu0">0</span><span class="br0">)</span></p>
<p><span class="kw1">and</span> <span class="br0">(</span>color == <span class="st0">&#8216;red&#8217;</span><span class="br0">)</span> <span class="kw1">and</span> <span class="br0">(</span>emphasis == <span class="st0">&#8216;strong&#8217;</span><span class="br0">)</span><span class="br0">)</span>:</p>
<p class="vspace">当表示文本的字符串（literal string）一行放不下的时候，用圆括号把隐含的连接行括起来。</p>
<div id="sourceblock25" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p>x = <span class="br0">(</span><span class="st0">&#8216;This will build a very long long &#8216;</span></p>
<p><span class="st0">&#8216;long long long long long long string&#8217;</span><span class="br0">)</span></p>
</div>
</div>
</div>
<p class="vspace">注意上例中连续行中元素的缩进，参考<a href="#Indentation">缩进</a>章节的解释。</p>
<h2 style="margin-top: 0px;"><a id="toc27" name="toc27"></a>3.3  圆括号 <a id="Parentheses" name="Parentheses"></a></h2>
<p>吝啬地使用圆括号。在以下情况下别用：</p>
<ul>
<li>在 <span style="color: blue;">return</span> 语句中。</li>
<li>在条件判断语句中。除非是用圆括号来暗示两行是连在一起的（参见上一节）。</li>
<li>在元组（tuple）周围。除非因为语法而不得不加或是为了显得更清晰。</li>
</ul>
<p class="vspace">但在下列情况下是可以用圆括号的：</p>
<ul>
<li>暗示两行是连在一起的。</li>
<li>用来括起长表达式中的子表达式（包括子表达式是条件判断语句一部分的情形）。</li>
</ul>
<p class="vspace">实际上，在子表达式周围用圆括号比单纯依赖运算符优先级要好。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span></p>
<div id="sourceblock26" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">if</span> foo:</p>
<p><span class="kw1">while</span> x:</p>
<p><span class="kw1">if</span> x <span class="kw1">and</span> y:</p>
<p><span class="kw1">if</span> <span class="kw1">not</span> x:</p>
<p><span class="kw1">if</span> <span class="br0">(</span>x <span class="sy0">&lt;</span> <span class="nu0">3</span><span class="br0">)</span> <span class="kw1">and</span> <span class="br0">(</span><span class="kw1">not</span> y<span class="br0">)</span>:</p>
<p><span class="kw1">return</span> foo</p>
<p><span class="kw1">for</span> x, y <span class="kw1">in</span> <span class="kw2">dict</span>.<span class="me1">items</span><span class="br0">(</span><span class="br0">)</span>:</p>
<p>x, <span class="br0">(</span>y, z<span class="br0">)</span> = funcThatReturnsNestedTuples<span class="br0">(</span><span class="br0">)</span></p>
</div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span></p>
<div id="sourceblock27" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">if</span> <span class="br0">(</span>x<span class="br0">)</span>:</p>
<p><span class="kw1">while</span> <span class="br0">(</span>x<span class="br0">)</span>:</p>
<p><span class="kw1">if</span> <span class="kw1">not</span><span class="br0">(</span>x<span class="br0">)</span>:</p>
<p><span class="kw1">if</span> <span class="br0">(</span><span class="br0">(</span>x <span class="sy0">&lt;</span> <span class="nu0">3</span><span class="br0">)</span> <span class="kw1">and</span> <span class="br0">(</span><span class="kw1">not</span> y<span class="br0">)</span><span class="br0">)</span>:</p>
<p><span class="kw1">return</span> <span class="br0">(</span>foo<span class="br0">)</span></p>
<p><span class="kw1">for</span> <span class="br0">(</span>x, y<span class="br0">)</span> <span class="kw1">in</span> <span class="kw2">dict</span>.<span class="me1">items</span><span class="br0">(</span><span class="br0">)</span>:</p>
<p><span class="br0">(</span>x, <span class="br0">(</span>y, z<span class="br0">)</span><span class="br0">)</span> = funcThatReturnsNestedTuples<span class="br0">(</span><span class="br0">)</span></p>
</div>
</div>
</div>
<div class="sectionedit"><a name="sPython.PythonStyleGuide_28"><br />
</a></div>
<h2 style="margin-top: 0px;"><a id="toc28" name="toc28"></a>3.4  缩进 <a id="Indentation" name="Indentation"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">注意和<a class="urllink" style="color: red;" href="http://www.python.org/dev/peps/pep-0008/" rel="nofollow">PEP8</a>不同，这里遵循作为本文起源的原始 Google Python 编码风格指南。</span></p>
<p class="vspace">用两空格缩进代码块。不要用 tab 或者混用 tab 和空格。如果要暗示两行相连，要么就把被包装的元素纵向对其，就像“每行长度”章节中的例子那样；要么就用<span style="color: red; font-size: 120%; font-weight: bold;">4</span>个空格（不是两个，这样可以和后面紧跟着的嵌套代码块区分开，避免混淆）作悬挂缩进（hanging indent），在这种情况下，首行不应该放任何参数。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span></p>
<div id="sourceblock28" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="co1"># 与起始定界符对齐：</span></p>
<p>foo = longFunctionName<span class="br0">(</span>var_one, var_two,</p>
<p>var_three, var_four<span class="br0">)</span></p>
</div>
</div>
</div>
<p><span class="co1"># 4空格悬挂缩进，而且首行空着：</span></p>
<p>foo = longFunctionName<span class="br0">(</span></p>
<p>var_one, var_two, var_three,</p>
<p>var_four<span class="br0">)</span></p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span></p>
<div id="sourceblock29" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="co1"># 不应该在首行塞东西：</span></p>
<p>foo = longFunctionName<span class="br0">(</span>var_one, var_two,</p>
<p>var_three, var_four<span class="br0">)</span></p>
</div>
</div>
</div>
<p><span class="co1"># 不应该用两空格的悬挂缩进：</span></p>
<p>foo = longFunctionName<span class="br0">(</span></p>
<p>var_one, var_two, var_three,</p>
<p>var_four<span class="br0">)</span></p>
<div class="sectionedit"><a name="sPython.PythonStyleGuide_29"><br />
</a></div>
<h2 style="margin-top: 0px;"><a id="toc29" name="toc29"></a>3.5  空行 <a id="Blank_lines" name="Blank_lines"></a></h2>
<p>在顶级定义（可以是函数或者类定义）之间加两个空行。在方法定义之间以及“ class ”那一行与第一个方法之间加一个空行。在<a href="#Doc_strings">__doc__ string</a>和它后面的代码之间加一个空行。在函数和方法内部你认为合适的地方加一个空行。</p>
<p class="vspace">在文件最后总是加一个空行，这可以避免很多 diff 工具生成“No newline at end of file”信息。</p>
<h2 style="margin-top: 0px;"><a id="toc30" name="toc30"></a>3.6  空格 <a id="Whitespace" name="Whitespace"></a></h2>
<p>在圆括号、方括号、大括号里面不要加空格。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span> <span style="color: blue;">spam(ham[1], {eggs: 2}, [])</span></p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span> <span style="color: blue;">spam( ham[ 1 ], { eggs: 2 }, [ ] )</span></p>
<p class="vspace">在逗号、分号、冒号前面不要加空格。逗号、分号、冒号后面<span style="color: red; font-size: 120%; font-weight: bold;">必须</span>加空格，除非那是行尾。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span></p>
<div id="sourceblock30" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">if</span> x == <span class="nu0">4</span>:</p>
<p><span class="kw1">print</span> x, y</p>
<p>x, y = y, x</p>
</div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span></p>
<div id="sourceblock31" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">if</span> x == <span class="nu0">4</span> :</p>
<p><span class="kw1">print</span> x , y</p>
<p>x , y = y , x</p>
</div>
</div>
</div>
<p class="vspace">在表示参数、列表、下标、分块开始的圆括号/方括号前面不要加空格。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span> <span style="color: blue;">spam(1)</span></p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span> <span style="color: blue;">spam (1)</span></p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span> <span style="color: blue;">dict['key'] = list[index]</span></p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span> <span style="color: blue;">dict ['key'] = list [index]</span></p>
<p class="vspace">在二元运算符两边各家一个空格，包括：赋值（<span style="color: blue;">=</span>）、比较（<span style="color: blue;">==</span>、<span style="color: blue;">&lt;</span>、<span style="color: blue;">&gt;</span>、<span style="color: blue;">!=</span>、<span style="color: blue;">&lt;&gt;</span>、<span style="color: blue;">&lt;=</span>、<span style="color: blue;">&gt;=</span>、<span style="color: blue;">in</span>、<span style="color: blue;">not in</span>、<span style="color: blue;">is</span>、<span style="color: blue;">is not</span>）、以及布尔运算符（<span style="color: blue;">and</span>、<span style="color: blue;">or</span>、<span style="color: blue;">not</span>）。你肯定能判断出是否应该在算术运算符周围加空格，因为在二元运算符两边加空格的原则总是一致的。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span> <span style="color: blue;">x == 1</span></p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span> <span style="color: blue;">x&lt;1</span></p>
<p class="vspace">等号（“=”）用于指名参数或默认参数值时，两边不要加空格。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span> <span style="color: blue;">def Complex(real, imag=0.0): return Magic(r=real, i=imag)</span></p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span> <span style="color: blue;">def Complex(real, imag = 0.0): return Magic(r = real, i = imag)</span></p>
<h2 style="margin-top: 0px;"><a id="toc31" name="toc31"></a>3.7  Python 解释器 <a id="Python_Interpreter" name="Python_Interpreter"></a></h2>
<p>模块开头应该是一个“shebang”行，用于指定执行此程序的 Python 解释器：</p>
<div id="sourceblock32" class="sourceblock ">
<div class="sourceblocktext">
<div class="python"><span class="co1">#!/usr/bin/python2.5</span></div>
</div>
</div>
<p class="vspace"><a class="urllink" href="http://code.google.com/appengine/docs/python/purepython.html" rel="nofollow">Google App Engine 要求使用 Python 2.5</a>。</p>
<h2 style="margin-top: 0px;"><a id="toc32" name="toc32"></a>3.8  注释 <a id="Comments" name="Comments"></a></h2>
<h3 style="margin-top: 0px;">Doc strings <a id="Doc_strings" name="Doc_strings"></a></h3>
<p>Python 有一种独特的注释风格称为 <span style="color: blue;">__doc__</span> String。包、模块、类、函数的第一个语句如果是字符串那么就是一个 <span style="color: blue;">__doc__</span> String。这种字符串可以用对象的 <span style="color: blue;">__doc__()</span> 成员函数自动提取，而且会被用于 <span style="color: blue;">pydoc</span>。（试着在你的模块上运行 <span style="color: blue;">pydoc</span> 来看看它是怎么工作的。）我们对 <span style="color: blue;">__doc__</span> String 的约定是：用三个双引号把字符串括起来。 <span style="color: blue;">__doc__</span> String 应该这样组织：首先是一个以句号结束的摘要行（实实在在的一行，<a href="#Line_length">不多于80个字符</a>），然后接一个空行，再接 <span style="color: blue;">__doc__</span> String 中的其他内容，并且这些文字的起始位置要和首行的第一个双引号在同一列。下面几节是关于 <span style="color: blue;">__doc__</span> String 格式更进一步的原则</p>
<h3 style="margin-top: 0px;">模块 <a id="Modules" name="Modules"></a></h3>
<p>每个文件开头都应该包含一个带有版权信息和许可声明的块注释。</p>
<h4 style="margin-top: 0px;">版权和许可声明</h4>
<div id="sourceblock33" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="co1">#!/usr/bin/python2.5</span></p>
<p><span class="co1">#</span></p>
<p><span class="co1"># Copyright [current year] the Melange authors.</span></p>
<p><span class="co1">#</span></p>
<p><span class="co1"># Licensed under the Apache License, Version 2.0 (the “License”);</span></p>
<p><span class="co1"># you may not use this file except in compliance with the License.</span></p>
<p><span class="co1"># You may obtain a copy of the License at</span></p>
<p><span class="co1"># </span></p>
<p><span class="co1">#   http://www.apache.org/licenses/LICENSE-2.0</span></p>
<p><span class="co1"># </span></p>
<p><span class="co1"># Unless required by applicable law or agreed to in writing, software</span></p>
<p><span class="co1"># distributed under the License is distributed on an “AS IS” BASIS,</span></p>
<p><span class="co1"># WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></p>
<p><span class="co1"># See the License for the specific language governing permissions and</span></p>
<p><span class="co1"># limitations under the License.</span></p>
</div>
</div>
</div>
<p class="vspace">然后接着写描述模块内容的<span style="color: blue;">__doc__</span> String，其中作者信息应该紧跟着许可声明。如果还给出了作者邮件地址，那添加到 <span style="color: blue;">__authors__</span> 列表的整个作者字符串应该就是一个<a class="urllink" href="http://www.ietf.org/rfc/rfc2821.txt" rel="nofollow">与 RFC 2821 兼容的</a>电子邮件地址。</p>
<h4 style="margin-top: 0px;">模块头及作者信息</h4>
<div id="sourceblock34" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="st0">“”"用一行文字概述模块或脚本，用句号结尾。</span></p>
<p>留一个空行。本 __doc__ string 的其他部分应该包括模块或脚本的全面描述。作为可选项，还可以包括导出的类和函数的简要描述。</p>
<p>ClassFoo: 一行概述。</p>
<p>functionBar(): 一行概述。</p>
<p>“”"</p>
<p>__authors__ = <span class="br0">[</span></p>
<p><span class="co1"># 请按照姓氏字母顺序排列：</span></p>
<p><span class="st0">'"John Smith" &lt;johnsmith@example.com&gt;'</span>,</p>
<p><span class="st0">'"Joe Paranoid" &lt;joeisgone@example.com&gt;'</span>,  <span class="co1"># 应提供电子邮件地址</span></p>
<p><span class="br0">]</span></p>
</div>
</div>
</div>
<p class="vspace">如果新的贡献者还没添加到<a class="urllink" href="http://soc.googlecode.com/svn/trunk/AUTHORS" rel="nofollow">AUTHORS file</a>中，那应该在该贡献者第一次向版本控制工具提交代码时同时把他/她添加到这个文件里。</p>
<h3 style="margin-top: 0px;">函数和方法 <a id="Functions_and_Methods" name="Functions_and_Methods"></a></h3>
<p>如果不是用途非常明显而且非常短的话，所有函数和方法都应该有 <span style="color: blue;">__doc__</span> string 。此外，所有外部能访问的函数和方法，无论有多短、有多简单，都应该有 <span style="color: blue;">__doc__</span> string 。 <span style="color: blue;">__doc__</span> string 应该包括函数能做什么、输入数据的具体描述（“<span style="color: blue;">Args:</span>”）、输出数据的具体描述（“<span style="color: blue;">Returns:</span>”、“<span style="color: blue;">Raises:</span>”、或者“<span style="color: blue;">Yields:</span>”）。 <span style="color: blue;">__doc__</span> string 应该能提供调用此函数相关的足够信息，而无需让使用者看函数的实现代码。如果参数要求特定的数据类型或者设置了参数默认值，那 <span style="color: blue;">__doc__</span> string 应该明确说明这两点。“<span style="color: blue;">Raises:</span>”部分应该列出此函数可能抛出的所有异常。生成器函数的 <span style="color: blue;">__doc__</span> string 应该用“<span style="color: blue;">Yields:</span>”而不是<span style="color: blue;">Returns:</span>。</p>
<p class="vspace">函数和方法的 <span style="color: blue;">__doc__</span> string 一般不应该描述实现细节，除非其中涉及非常复杂的算法。在难以理解的代码中使用块注释或行内注释会是更合适的做法。</p>
<div id="sourceblock35" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">def</span> fetchRows<span class="br0">(</span>table, keys<span class="br0">)</span>:</p>
<p><span class="st0">“”"取出表中的多行内容。</span></p>
</div>
</div>
</div>
<p>Args:</p>
<p>table: 打开的表。 Table 类的实例。</p>
<p>keys: 字符串序列，表示要从表中取出的行的键值。</p>
<p>Returns:</p>
<p>一个字典，映射指定键值与取出的表中对应行的数据：</p>
<p>{&#8216;Serak&#8217;: (&#8216;Rigel VII&#8217;, &#8216;Preparer&#8217;),</p>
<p>&#8216;Zim&#8217;: (&#8216;Irk&#8217;, &#8216;Invader&#8217;),</p>
<p>&#8216;Lrrr&#8217;: (&#8216;Omicron Persei 8&#8242;, &#8216;Emperor&#8217;)}</p>
<p>如果 keys 参数中的键值没有出现在字典里，就表示对应行在表中没找到。</p>
<p>Raises:</p>
<p>IOError: 访问 table.Table 对象时发生的错误。</p>
<p>“”"</p>
<p><span class="kw1">pass</span></p>
<h3 style="margin-top: 0px;">类 <a id="Classes" name="Classes"></a></h3>
<p>类应该在描述它的类定义下面放 <span style="color: blue;">__doc__</span> string 。如果你的类有公开属性值，那应该在 <span style="color: blue;">__doc__</span> string 的 <span style="color: blue;">Attributes:</span> 部分写清楚。</p>
<div id="sourceblock36" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">class</span> SampleClass<span class="br0">(</span><span class="kw2">object</span><span class="br0">)</span>:</p>
<p><span class="st0">“”"这里是类的概述。</span></p>
<p>详细的描述信息……</p>
<p>详细的描述信息……</p>
<p>Attributes:</p>
<p>likes_spam: 布尔型，表示我们是否喜欢垃圾邮件。</p>
<p>eggs: 整数，数我们下了多少蛋。</p>
<p>“”"</p>
<p><span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">(</span><span class="kw2">self</span>, likes_spam=<span class="kw2">False</span><span class="br0">)</span>:</p>
<p><span class="st0">“”"拿点什么来初始化 SampleClass 。</span></p>
<p>Args:</p>
<p>likes_spam: 初始化指标，表示 SampleClass 实例是否喜欢垃圾邮件（默认是 False）。</p>
<p>“”"</p>
<p><span class="kw2">self</span>.<span class="me1">likes_spam</span> = likes_spam</p>
<p><span class="kw2">self</span>.<span class="me1">eggs</span> = <span class="nu0">0</span></p>
<p><span class="kw1">def</span> publicMethod<span class="br0">(</span><span class="kw2">self</span><span class="br0">)</span>:</p>
<p><span class="st0">“”"执行一些操作。”"”</span></p>
<p><span class="kw1">pass</span></p>
</div>
</div>
</div>
<h3 style="margin-top: 0px;">块注释及行内注释 <a id="Block_and_Inline_Comments" name="Block_and_Inline_Comments"></a></h3>
<p>加注释的最后一个位置是在难以理解的代码里面。如果你打算在下一次代码复查（code review）的时候解释这是什么意思，那你应该现在就把它写成注释。在开始进行操作之前，就应该给复杂的操作写几行注释。对不直观的代码则应该在行末写注释。</p>
<div id="sourceblock37" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="co1"># 我们用带权的字典检索来查找 i 在数组中的位置。我们根据数组中最大的数和</span></p>
<p><span class="co1"># 数组的长度来推断可能的位置，然后做二分法检索找到准确的值。</span></p>
</div>
</div>
</div>
<p><span class="kw1">if</span> i <span class="sy0">&amp;</span> <span class="br0">(</span>i-<span class="nu0">1</span><span class="br0">)</span> == <span class="nu0">0</span>:        <span class="co1"># 当且仅当 i 是 2 的幂时，值为 true</span></p>
<p class="vspace">这些注释应该和代码分开才更易读。在块注释值钱应该加一个空行。一般行末注释应该和代码之间至少空两个格。如果连续几行都有行末注释（或者是在一个函数中），<span style="color: red; font-size: 120%; font-weight: bold;">可以</span>把它们纵向对齐，但这不是必须的。</p>
<p class="vspace">另一方面，不要重复描述代码做的事。假设正在读代码的人比你更懂 Python （尽管这不是你努力的方向）。<br />
On the other hand, never describe the code. Assume the person reading<br />
the code knows Python (though not what you&#8217;re trying to do) better<br />
than you do.</p>
<div id="sourceblock38" class="sourceblock ">
<div class="sourceblocktext">
<div class="python"><span class="co1"># *不好的注释*：现在要遍历数组 b 并且确保任何时候 i 出现时，下一个元素都是 i+1</span></div>
</div>
</div>
<h2 style="margin-top: 0px;"><a id="toc33" name="toc33"></a>3.9  类</h2>
<p>如果不从其他基类继承，那就应该明确地从 <span style="color: blue;">object</span> 基类继承。这一条对嵌套类也适用。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span></p>
<div id="sourceblock39" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">class</span> SampleClass:</p>
<p><span class="kw1">pass</span></p>
</div>
</div>
</div>
<p><span class="kw1">class</span> OuterClass:</p>
<p><span class="kw1">class</span> InnerClass:</p>
<p><span class="kw1">pass</span></p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span></p>
<div id="sourceblock40" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">class</span> SampleClass<span class="br0">(</span><span class="kw2">object</span><span class="br0">)</span>:</p>
<p><span class="kw1">pass</span></p>
</div>
</div>
</div>
<p><span class="kw1">class</span> OuterClass<span class="br0">(</span><span class="kw2">object</span><span class="br0">)</span>:</p>
<p><span class="kw1">class</span> InnerClass<span class="br0">(</span><span class="kw2">object</span><span class="br0">)</span>:</p>
<p><span class="kw1">pass</span></p>
<p><span class="kw1">class</span> ChildClass<span class="br0">(</span>ParentClass<span class="br0">)</span>:</p>
<p><span class="st0">“”"已经从另一个类显式继承了。”"”</span></p>
<p><span class="kw1">pass</span></p>
<p class="vspace">从 <span style="color: blue;">object</span> 继承是为了让类属性能够正常工作，这会避免我们一旦切换到 Python 3000 时，打破已经习惯了的特有风格。同时这也定义了一些特殊函数，来实现对象（object）的默认语义，包括：<span style="color: blue;">__new__</span>、<span style="color: blue;">__init__</span>、<span style="color: blue;">__delattr__</span>、<span style="color: blue;">__getattribute__</span>、<span style="color: blue;">__setattr__</span>、<span style="color: blue;">__hash__</span>、<span style="color: blue;">__repr__</span>、和 <span style="color: blue;">__str__</span>。</p>
<h2 style="margin-top: 0px;"><a id="toc34" name="toc34"></a>3.10  字符串 <a id="Strings" name="Strings"></a></h2>
<p>应该用 <span style="color: blue;"> % </span> 运算符来格式化字符串，即使所有的参数都是字符串。不过你也可以在 <span style="color: blue;">+</span> 和 <span style="color: blue;"> % </span> 之间做出你自己最明智的判断。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span></p>
<div id="sourceblock41" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p>x = <span class="st0">&#8216;%s%s&#8217;</span> <span class="sy0">%</span> <span class="br0">(</span>a, b<span class="br0">)</span>  <span class="co1"># 这种情况下应该用 + </span></p>
<p>x = imperative + <span class="st0">&#8216;, &#8216;</span> + expletive + <span class="st0">&#8216;!&#8217;</span></p>
<p>x = <span class="st0">&#8216;name: &#8216;</span> + name + <span class="st0">&#8216;; score: &#8216;</span> + <span class="kw2">str</span><span class="br0">(</span>n<span class="br0">)</span></p>
</div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span></p>
<div id="sourceblock42" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p>x = a + b</p>
<p>x = <span class="st0">&#8216;%s, %s!&#8217;</span> <span class="sy0">%</span> <span class="br0">(</span>imperative, expletive<span class="br0">)</span></p>
<p>x = <span class="st0">&#8216;name: %s; score: %d&#8217;</span> <span class="sy0">%</span> <span class="br0">(</span>name, n<span class="br0">)</span></p>
</div>
</div>
</div>
<p class="vspace">应该避免在循环中用 <span style="color: blue;">+</span> 或 <span style="color: blue;">+=</span> 来连续拼接字符串。因为字符串是不变型，这会毫无必要地建立很多临时对象，从而二次方级别的运算量而不是线性运算时间。相反，应该把每个子串放到 <span style="color: blue;">list</span> 里面，然后在循环结束的时候用 <span style="color: blue;">”.join()</span> 拼接这个列表。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span></p>
<div id="sourceblock43" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p>employee_table = <span class="st0">&#8216;&lt;table&gt;&#8217;</span></p>
<p><span class="kw1">for</span> last_name, first_name <span class="kw1">in</span> employee_list:</p>
<p>employee_table += <span class="st0">&#8216;&lt;tr&gt;&lt;td&gt;%s, %s&lt;/td&gt;&lt;/tr&gt;&#8217;</span> <span class="sy0">%</span> <span class="br0">(</span>last_name, first_name<span class="br0">)</span></p>
<p>employee_table += <span class="st0">&#8216;&lt;/table&gt;&#8217;</span></p>
</div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span></p>
<div id="sourceblock44" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p>items = <span class="br0">[</span><span class="st0">'&lt;table&gt;'</span><span class="br0">]</span></p>
<p><span class="kw1">for</span> last_name, first_name <span class="kw1">in</span> employee_list:</p>
<p>items.<span class="me1">append</span><span class="br0">(</span><span class="st0">&#8216;&lt;tr&gt;&lt;td&gt;%s, %s&lt;/td&gt;&lt;/tr&gt;&#8217;</span> <span class="sy0">%</span> <span class="br0">(</span>last_name, first_name<span class="br0">)</span><span class="br0">)</span></p>
<p>items.<span class="me1">append</span><span class="br0">(</span><span class="st0">&#8216;&lt;/table&gt;&#8217;</span><span class="br0">)</span></p>
<p>employee_table = <span class="st0">”</span>.<span class="me1">join</span><span class="br0">(</span>items<span class="br0">)</span></p>
</div>
</div>
</div>
<p class="vspace">对多行字符串使用 <span style="color: blue;">“”"</span> 而不是 <span style="color: blue;">”&#8217;</span>。但是注意，通常使用隐含的行连接（implicit line joining）会更清晰，因为多行字符串不符合程序其他部分的缩进风格。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span></p>
<div id="sourceblock45" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">print</span> <span class="st0">“”"这种风格非常恶心。</span></p>
<p>不要这么用。</p>
<p>“”"</p>
</div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span></p>
<div id="sourceblock46" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">print</span> <span class="br0">(</span><span class="st0">“这样会好得多。<span class="es0">\n</span>“</span></p>
<p><span class="st0">“所以应该这样用。<span class="es0">\n</span>“</span><span class="br0">)</span></p>
</div>
</div>
</div>
<h2 style="margin-top: 0px;"><a id="toc35" name="toc35"></a>3.11  TODO style <a id="TODO_style" name="TODO_style"></a></h2>
<p>在代码中使用 <span style="color: blue;">TODO</span> 注释是临时的、短期的解决方案，或者说是足够好但不够完美的办法。</p>
<p class="vspace"><span style="color: blue;">TODO</span> 应该包括全部大写的字符串 <span style="color: blue;">TODO</span> ，紧接用圆括号括起来的你的用户名： <span style="color: blue;">TODO(username)</span> 。其中冒号是可选的。主要目的是希望有一种一致的 <span style="color: blue;">TODO</span> 格式，而且可以通过用户名检索。</p>
<div id="sourceblock47" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="co1"># TODO(someuser): 这里应该用 “*” 来做级联操作。</span></p>
<p><span class="co1"># TODO(anotheruser) 用 relations 来修改这儿。</span></p>
</div>
</div>
</div>
<p class="vspace">如果你的 <span style="color: blue;">TODO</span> 是“在未来某个时间做某事”的形式，确保你要么包括非常确定的日期（“Fix by November 2008”）或者非常特殊的事件（“在数据库中的 Foo 实体都加上新的 fubar 属性之后删除这段代码。”）。</p>
<h2 style="margin-top: 0px;"><a id="toc36" name="toc36"></a>3.12  import 分组及顺序 <a id="Imports_grouping_and_order" name="Imports_grouping_and_order"></a></h2>
<p>应该在不同的行中做 import ：</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span></p>
<div id="sourceblock48" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">import</span> <span class="kw3">sys</span></p>
<p><span class="kw1">import</span> <span class="kw3">os</span></p>
</div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span></p>
<div id="sourceblock49" class="sourceblock ">
<div class="sourceblocktext">
<div class="python"><span class="kw1">import</span> <span class="kw3">sys</span>, <span class="kw3">os</span></div>
</div>
</div>
<p class="vspace">import 总是放在文件开头的，也即在所有模块注释和 <span style="color: blue;">__doc__</span> string 的后面，在模块全局变量及常量的前面。import 应该按照从最常用到最不常用的顺序分组放置：</p>
<ul>
<li>import 标准库</li>
<li>import 第三方库</li>
<li>import Google App Engine 相关库</li>
<li>import Django 框架相关库</li>
<li>import <span class="wikiword">SoC</span> framework 相关库</li>
<li>import 基于 <span class="wikiword">SoC</span> 框架的模块</li>
<li>import 应用程序特有的内容</li>
</ul>
<p class="vspace">应该按照字母顺序排序，但所有以 <span style="color: blue;">from &#8230;</span> 开头的行都应该靠前，然后是一个空行，再然后是所有以 <span style="color: blue;">import &#8230;</span> 开头的行。以 <span style="color: blue;">import &#8230;</span> 开头的标准库和第三方库的 import 应该放在最前面，而且和其他分组隔开：</p>
<div id="sourceblock50" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">import</span> a_standard</p>
<p><span class="kw1">import</span> b_standard</p>
<p><span class="kw1">import</span> a_third_party</p>
<p><span class="kw1">import</span> b_third_party</p>
</div>
</div>
</div>
<p><span class="kw1">from</span> a_soc <span class="kw1">import</span> f</p>
<p><span class="kw1">from</span> a_soc <span class="kw1">import</span> g</p>
<p><span class="kw1">import</span> a_soc</p>
<p><span class="kw1">import</span>b_soc</p>
<p class="vspace">在 import/from 行中，语句应该按照字母顺序排序：</p>
<div id="sourceblock51" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">from</span> a <span class="kw1">import</span> f</p>
<p><span class="kw1">from</span> a <span class="kw1">import</span> g</p>
<p><span class="kw1">from</span> a.<span class="me1">b</span> <span class="kw1">import</span> h</p>
<p><span class="kw1">from</span> a.<span class="me1">d</span> <span class="kw1">import</span> e</p>
</div>
</div>
</div>
<p><span class="kw1">import</span> a.<span class="me1">b</span></p>
<p><span class="kw1">import</span> a.<span class="me1">b</span>.<span class="me1">c</span></p>
<p><span class="kw1">import</span> a.<span class="me1">d</span>.<span class="me1">e</span></p>
<h2 style="margin-top: 0px;"><a id="toc37" name="toc37"></a>3.13  语句 <a id="Statements" name="Statements"></a></h2>
<p>一般一行只放一个语句。但你可以把测试和测试结果放在一行里面，只要这样做合适。具体来说，你不能这样写 <span style="color: blue;">try/except</span> ，因为 <span style="color: blue;">try</span> 和 <span style="color: blue;">except</span> 不适合这样，你只可以对不带 <span style="color: blue;">else</span> 的 <span style="color: blue;">if</span> 这么干。</p>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">Yes：</span></p>
<div id="sourceblock52" class="sourceblock ">
<div class="sourceblocktext">
<div class="python"><span class="kw1">if</span> foo: fuBar<span class="br0">(</span>foo<span class="br0">)</span></div>
</div>
</div>
<p class="vspace"><span style="color: red; font-size: 120%; font-weight: bold;">No：</span></p>
<div id="sourceblock53" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">if</span> foo: fuBar<span class="br0">(</span>foo<span class="br0">)</span></p>
<p><span class="kw1">else</span>:   fuBaz<span class="br0">(</span>foo<span class="br0">)</span></p>
</div>
</div>
</div>
<p><span class="kw1">try</span>:               fuBar<span class="br0">(</span>foo<span class="br0">)</span></p>
<p><span class="kw1">except</span> <span class="kw2">ValueError</span>: fuBaz<span class="br0">(</span>foo<span class="br0">)</span></p>
<p><span class="kw1">try</span>:</p>
<p>fuBar<span class="br0">(</span>foo<span class="br0">)</span></p>
<p><span class="kw1">except</span> <span class="kw2">ValueError</span>: fuBaz<span class="br0">(</span>foo<span class="br0">)</span></p>
<h2 style="margin-top: 0px;"><a id="toc38" name="toc38"></a>3.14  访问控制 <a id="Access_control" name="Access_control"></a></h2>
<p>如果存取器函数很简单，那你应该用公开的变量来代替它，以避免 Python 中函数调用的额外消耗。在更多功能被加进来时，你可以用 Property 特性来保持语法一致性。</p>
<p class="vspace">另一方面，如果访问更复杂，或者访问变量的成本较为显著，那你应该用函数调用（遵循<a href="#Naming">命名准则</a>），比如 <span style="color: blue;">getFoo()</span> 或者 <span style="color: blue;">setFoo()</span>。如果过去的行为允许通过 Property 访问，那就别把新的存取器函数绑定到 Property 上。所有仍然企图用旧方法访问变量的代码应该是非常显眼的，这样调用者会被提醒这种改变是比较复杂的。</p>
<h2 style="margin-top: 0px;"><a id="toc39" name="toc39"></a>3.15  命名 <a id="Naming" name="Naming"></a></h2>
<h3 style="margin-top: 0px;">要避免的命名方式</h3>
<ul>
<li>使用单个字符命名，除非是计数器或迭代器。</li>
<li>在任何包或模块的名字里面使用减号。</li>
<li><span style="color: blue;">__double_leading_and_trailing_underscore__</span> 在变量开头和结尾都使用两个下划线（在 Python 内部有特殊含义）。</li>
</ul>
<h3 style="margin-top: 0px;">命名约定</h3>
<p><span style="color: red; font-size: 120%; font-weight: bold;">注意这里某些命名约定和<a class="urllink" style="color: red;" href="http://www.python.org/dev/peps/pep-0008/" rel="nofollow">PEP8</a>不一样，而是遵循“Google Python 编码风格指南”的原始版本，也即本编码风格指南的起源。</span></p>
<ul>
<li>“Internal”表示模块内部或类中的保护域（protected）和私有域。</li>
<li>变量名开头加一个下划线（<span style="color: blue;">_</span>）能对保护模块中的变量及函数提供一些支持（不会被 <span style="color: blue;">import * from</span> 导入）。</li>
<li>在实例的变量和方法开头加两个下划线（<span style="color: blue;">__</span>）能有效地帮助把该变量或方法变成类的私有内容（using name mangling）。</li>
<li>把模块中相关的类和顶级函数放在一起。不像 <a href="http://www.zhblog.net/archives/tag/java" class="st_tag internal_tag" rel="tag" title="标签 java 下的日志">Java</a> ，这里无需要求自己在每个模块中只放一个类。但要确保放在同一模块中的类和顶级函数是<a class="urllink" href="http://en.wikipedia.org/wiki/Cohesion_computer_science" rel="nofollow">高内聚的</a>。</li>
<li>对类名使用驼峰式（形如 <span style="color: blue;"><span class="wikiword">CapWords</span></span>），而对模块名使用下划线分隔的小写字母（<span style="color: blue;">lower_with_under.py</span>）。</li>
</ul>
<h3 style="margin-top: 0px;">命名样例</h3>
<table width="100%">
<tbody>
<tr class="row1">
<td align="center"><span style="color: red; font-size: 120%; font-weight: bold;">类别</span></td>
<td align="center"><span style="color: red; font-size: 120%; font-weight: bold;">公开的</span></td>
<td align="center"><span style="color: red; font-size: 120%; font-weight: bold;">内部的</span></td>
</tr>
<tr class="row1">
<td align="center"><em>Packages</em></td>
<td align="center"><span style="color: blue;">lower_with_under</span></td>
<td></td>
</tr>
<tr class="row1">
<td align="center"><em>Modules</em></td>
<td align="center"><span style="color: blue;">lower_with_under</span></td>
<td align="center"><span style="color: blue;">_lower_with_under</span></td>
</tr>
<tr class="row1">
<td align="center"><em>Classes</em></td>
<td align="center"><span style="color: blue;"><span class="wikiword">CapWords</span></span></td>
<td align="center"><span style="color: blue;">_CapWords</span></td>
</tr>
<tr class="row1">
<td align="center"><em>Exceptions</em></td>
<td align="center"><span style="color: blue;"><span class="wikiword">CapWords</span></span></td>
<td></td>
</tr>
<tr class="row1">
<td align="center"><em>Functions</em></td>
<td align="center"><span style="color: blue;">firstLowerCapWords()</span></td>
<td align="center"><span style="color: blue;">_firstLowerCapWords()</span></td>
</tr>
<tr class="row1">
<td align="center"><em>Global/Class Constants</em></td>
<td align="center"><span style="color: blue;">CAPS_WITH_UNDER</span></td>
<td align="center"><span style="color: blue;">_CAPS_WITH_UNDER</span></td>
</tr>
<tr class="row1">
<td align="center"><em>Global/Class Variables</em></td>
<td align="center"><span style="color: blue;">lower_with_under</span></td>
<td align="center"><span style="color: blue;">_lower_with_under</span></td>
</tr>
<tr class="row1">
<td align="center"><em>Instance Variables</em></td>
<td align="center"><span style="color: blue;">lower_with_under</span></td>
<td align="center"><span style="color: blue;">_lower_with_under</span> <em>(protected)</em> or <span style="color: blue;">__lower_with_under</span> <em>(private)</em></td>
</tr>
<tr class="row1">
<td align="center"><em>Method Names</em> <sup>*</sup></td>
<td align="center"><span style="color: blue;">firstLowerCapWords()</span></td>
<td align="center"><span style="color: blue;">_firstLowerCapWords()</span> <em>(protected)</em> or <span style="color: blue;">__firstLowerCapWords()</span> <em>(private)</em></td>
</tr>
<tr class="row1">
<td align="center"><em>Function/Method Parameters</em></td>
<td align="center"><span style="color: blue;">lower_with_under</span></td>
<td></td>
</tr>
<tr class="row1">
<td align="center"><em>Local Variables</em></td>
<td align="center"><span style="color: blue;">lower_with_under</span></td>
<td></td>
</tr>
</tbody>
</table>
<p class="vspace"><sup>*</sup> 考虑只在首选项设置中使用<a href="#Access_control">对公开属性的直接访问</a>来作为 getters 和 setters，因为函数调用在 Python 中是比较昂贵的，而 <span style="color: blue;">property</span> 之后可以用来把属性访问转化为函数调用而无需改变访问语法。</p>
<h2 style="margin-top: 0px;"><a id="toc40" name="toc40"></a>3.16  程序入口 <a id="Main" name="Main"></a></h2>
<p>所有的 Python 源代码文件都应该是可导入的。在 Python 中，<span style="color: blue;">pychecker</span>、 <span style="color: blue;">pydoc</span>、 以及单元测试都要求模块是可导入的。你的代码应该总是在执行你的主程序之前检查<span style="color: blue;">if __name__ == &#8216;__main__&#8217;:</span> ，这样就不会在模块被导入时执行主程序。大写 <span style="color: blue;">main()</span> 是故意要和命名约定的其他部分不一致，也就是说建议写成 <span style="color: blue;">Main()</span> 。</p>
<div id="sourceblock54" class="sourceblock ">
<div class="sourceblocktext">
<div class="python">
<p><span class="kw1">if</span> __name__ == <span class="st0">&#8216;__main__&#8217;</span>:</p>
<p><span class="co1"># 参数解析</span></p>
<p>main<span class="br0">(</span><span class="br0">)</span></p>
</div>
</div>
</div>
<p class="vspace">在模块被导入时，所有顶级缩进代码会被执行。注意不要调用函数、创建对象、或者做其他在文件被 <span style="color: blue;">pycheck</span> 或 <span style="color: blue;">pydoc</span> 的时候不应该做的操作。</p>
<h2 style="margin-top: 0px;"><a id="toc41" name="toc41"></a>3.17  总结 <a id="Conclusion" name="Conclusion"></a></h2>
<p><span style="color: red; font-size: 120%; font-weight: bold;">要一致</span></p>
<p class="vspace">如果你在编写代码，花几分钟看看你周围的代码并且弄清它的风格。如果在 <span style="color: blue;">if</span> 语句周围使用了空格，那你也应该这样做。如果注释是用星号组成的小盒子围起来的，那你同样也应该这样写。</p>
<p class="vspace">编码风格原则的关键在于有一个编程的通用词汇表，这样人们可以人民可以集中到你要说什么而不是你要怎么说。我们在这里提供全局的编码风格规则以便人们知道这些词汇，但局部风格也重要。如果你加入文件中的代码看起来和里面已经有的代码截然不同，那在读者读它的时候就会被破坏节奏。尽量避免这样。</p>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.zhblog.net/archives/895.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python开发编码规范</title>
		<link>http://www.zhblog.net/archives/893.html</link>
		<comments>http://www.zhblog.net/archives/893.html#comments</comments>
		<pubDate>Tue, 19 Jul 2011 08:33:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[编程其他]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.zhblog.net/?p=893</guid>
		<description><![CDATA[这篇文档所给出的编码约定适用于在主要的Python发布版本中组成标准库的Python 代码，请查阅相关的关于在Python的C实现中C代码风格指南的描述。 这篇文档改编自Guido最初的《Python风格指南》一文，并从《Barry&#8217;s style guide》中添加了部分内容。在有冲突的地方，Guide的风格规则应该是符合本PEP的意图(译注：指当有冲突时，应以Guido风格为准)。这篇PEP仍然尚未完成(实际上，它可能永远都不会完成)。 在这篇风格指导中的一致性是重要的。在一个项目内的一致性更重要。在一个模块或函数内的一致性最重要。但最重要的是：知道何时会不一致——有时只是没有实施风格指导。当出现疑惑时，运用你的最佳判断，看看别的例子，然后决定怎样看起来更好。并且要不耻下问！ 打破一条既定规则的两个好理由： (1) 当应用这个规则是将导致代码可读性下降，即便对某人来说，他已经习惯于按这条规则来阅读代码了。 (2) 为了和周围的代码保持一致而打破规则(也许是历史原因)，虽然这也是个清除其它混乱的好机会(真正的XP风格)。 代码的布局 缩进 使用Emacs的Python-mode的默认值：4个空格一个缩进层次。对于确实古老的代码，你不希望产生混乱，可以继续使用8空格的制表符(8-space tabs)。Emacs Python-mode自动发现文件中主要的缩进层次，依此设定缩进参数。 制表符还是空格 永远不要混用制表符和空格。最流行的Python缩进方式是仅使用空格，其次是仅使用制表符，混合着制表符和空格缩进的代码将被转换成仅使用空格。(在Emacs中，选中整个缓冲区，按ESC-x去除制表符。)调用Python命令行解释器时使用-t选项，可对代码中不合法得混合制表符和空格发出警告，使用-tt时警告将变成错误。这些选项是被高度推荐的。 对于新的项目，强烈推荐仅使用空格而不是制表符。许多编辑器拥有使之易于实现的功能(在Emacs中，确认indent-tabs-mode是nil)。 行的最大长度 周围仍然有许多设备被限制在每行80字符：而且，窗口限制在80个字符。使将多个窗口并排放置成为可能。在这些设备上使用默认的折叠方式看起来有点丑陋。因此，请将所有行限制在最大79字符(Emacs准确得将行限制为长80字符)，对顺序排放的大块文本(文档字符串或注释)，推荐将长度限制在72字符。 折叠长行的首选方法是使用Pyhon支持的圆括号，方括号和花括号内的行延续。如果需要，你可以在表达式周围增加一对额外的圆括号，但是有时使用反斜杠看起来更好，确认恰当得缩进了延续的行。 Emacs的Python-mode正确得完成了这些。一些例子： #!Python class Rectangle(Blob)： def __init__(self，width，height，color=&#8217;black&#8217;，emphasis=None，highlight=0)： if width == 0 and height == 0 and \ color == &#8216;red&#8217; and emphasis == &#8216;strong&#8217; or \ highlight &#62; 100： raise ValueError， “sorry， you lose” [...]]]></description>
			<content:encoded><![CDATA[<p>这篇文档所给出的编码约定适用于在主要的Python发布版本中组成标准库的Python 代码，请查阅相关的关于在Python的C实现中C代码风格指南的描述。</p>
<p>这篇文档改编自Guido最初的《Python风格指南》一文，并从《Barry&#8217;s style guide》中添加了部分内容。在有冲突的地方，Guide的风格规则应该是符合本PEP的意图(译注：指当有冲突时，应以Guido风格为准)。这篇PEP仍然尚未完成(实际上，它可能永远都不会完成)。<br />
在这篇风格指导中的一致性是重要的。在一个项目内的一致性更重要。在一个模块或函数内的一致性最重要。但最重要的是：知道何时会不一致——有时只是没有实施风格指导。当出现疑惑时，运用你的最佳判断，看看别的例子，然后决定怎样看起来更好。并且要不耻下问！<br />
打破一条既定规则的两个好理由：<br />
(1) 当应用这个规则是将导致代码可读性下降，即便对某人来说，他已经习惯于按这条规则来阅读代码了。<br />
(2) 为了和周围的代码保持一致而打破规则(也许是历史原因)，虽然这也是个清除其它混乱的好机会(真正的XP风格)。<span id="more-893"></span></p>
<p><strong>代码的布局</strong><br />
<strong>缩进</strong><br />
使用Emacs的Python-mode的默认值：4个空格一个缩进层次。对于确实古老的代码，你不希望产生混乱，可以继续使用8空格的制表符(8-space tabs)。Emacs <a href="http://www.zhblog.net/archives/tag/python" class="st_tag internal_tag" rel="tag" title="标签 python 下的日志">Python</a>-mode自动发现文件中主要的缩进层次，依此设定缩进参数。</p>
<p><strong>制表符还是空格</strong><br />
永远不要混用制表符和空格。最流行的Python缩进方式是仅使用空格，其次是仅使用制表符，混合着制表符和空格缩进的代码将被转换成仅使用空格。(在Emacs中，选中整个缓冲区，按ESC-x去除制表符。)调用Python命令行解释器时使用-t选项，可对代码中不合法得混合制表符和空格发出警告，使用-tt时警告将变成错误。这些选项是被高度推荐的。<br />
对于新的项目，强烈推荐仅使用空格而不是制表符。许多编辑器拥有使之易于实现的功能(在Emacs中，确认indent-tabs-mode是nil)。</p>
<p><strong>行的最大长度</strong><br />
周围仍然有许多设备被限制在每行80字符：而且，窗口限制在80个字符。使将多个窗口并排放置成为可能。在这些设备上使用默认的折叠方式看起来有点丑陋。因此，请将所有行限制在最大79字符(Emacs准确得将行限制为长80字符)，对顺序排放的大块文本(文档字符串或注释)，推荐将长度限制在72字符。<br />
折叠长行的首选方法是使用Pyhon支持的圆括号，方括号和花括号内的行延续。如果需要，你可以在表达式周围增加一对额外的圆括号，但是有时使用反斜杠看起来更好，确认恰当得缩进了延续的行。<br />
Emacs的Python-mode正确得完成了这些。一些例子：<br />
#!Python<br />
class Rectangle(Blob)：<br />
def __init__(self，width，height，color=&#8217;black&#8217;，emphasis=None，highlight=0)：<br />
if width == 0 and height == 0 and \<br />
color == &#8216;red&#8217; and emphasis == &#8216;strong&#8217; or \<br />
highlight &gt; 100：<br />
raise ValueError， “sorry， you lose”<br />
if width == 0 and height == 0 and (color == &#8216;red&#8217; or<br />
emphasis is None)：<br />
raise ValueError，”I don&#8217;t think so”<br />
Blob.__init__(self，width，height，color，emphasis，highlight)</p>
<p><strong>空行</strong><br />
用两行空行分割顶层函数和类的定义，类内方法的定义用单个空行分割，额外的空行可被用于(保守的)分割相关函数组成的群，在一组相关的单句中间可以省略空行。(例如：一组哑元素)。<br />
当空行用于分割方法的定义时，在‘class’行和第一个方法定义之间也要有一个空行。在函数中使用空行时，请谨慎的用于表示一个逻辑段落。Python接受contol-L(即^L)换页符作为空格：Emacs(和一些打印工具)，视这个字符为页面分割符，因此在你的文件中，可以用他们来为相关片段分页。</p>
<p><strong>编码</strong><br />
Python核心发布中的代码必须始终使用ASCII或Latin-1编码(又名 ISO-8859-1)，使用ASCII的文件不必有编码cookie，Latin-1仅当注释或文档字符串涉及作者名字需要Latin-1时才被使用：<br />
另外使用\x转义字符是在字符串中包含非ASCII(non-ASCII)数据的首选方法。<br />
作为PEP 263实现代码的测试套件的部分文件是个例外。</p>
<p><strong>导入</strong><br />
通常应该在单独的行中导入(Imports)，例如：<br />
No：import sys， os<br />
Yes：import sys<br />
import os<br />
但是这样也是可以的：<br />
from types import StringType， ListType<br />
Imports 通常被放置在文件的顶部，仅在模块注释和文档字符串之后，在模块的全局变量和常量之前。Imports应该有顺序地成组安放：<br />
1、标准库的导入(Imports )<br />
2、相关的主包(major package)的导入(即，所有的email包在随后导入)<br />
3、特定应用的导入(imports)<br />
你应该在每组导入之间放置一个空行，对于内部包的导入是不推荐使用相对导入的，对所有导入都要使用包的绝对路径。<br />
从一个包含类的模块中导入类时，通常可以写成这样：<br />
from MyClass import MyClass<br />
from foo.bar.YourClass import YourClass<br />
如果这样写导致了本地名字冲突，那么就这样写<br />
import MyClass<br />
import foo.bar.YourClass<br />
即使用”MyClass.MyClass”和”foo.bar.YourClass.YourClass”</p>
<p><strong>表达式和语句中的空格</strong><br />
Guido不喜欢在以下地方出现空格：<br />
紧挨着圆括号，方括号和花括号的，如：”spam( ham[ 1 ]，{ eggs：2 } )”。要始终将它写成”spam(ham[1]，{eggs： 2})”。<br />
紧贴在逗号，分号或冒号前的，如：<br />
“if x == 4：print x，y：x，y = y，x”。要始终将它写成<br />
“if x == 4：print x，y：x，y = y，x”。<br />
紧贴着函数调用的参数列表前开式括号(open parenthesis )的，如”spam (1)”。要始终将它写成”spam(1)”。<br />
紧贴在索引或切片，开始的开式括号前的，如：<br />
“dict ['key'] = list [index]“。要始终将它写成”dict['key'] = list[index]“。<br />
在赋值(或其它)运算符周围的用于和其它并排的一个以上的空格，如：<br />
#!Python<br />
x= 1<br />
y= 2<br />
long_variable = 3<br />
要始终将它写成<br />
#!Python<br />
x = 1<br />
y = 2<br />
long_variable = 3<br />
(不要对以上任意一条和他争论——Guido 养成这样的风格超过20年了。)</p>
<p><strong>其它建议</strong><br />
始终在这些二元运算符两边放置一个空格：赋值(=)， 比较(==，，!=，&lt;&gt;，=，in，not in，is，is not)，布尔运算 (and，or，not)。<br />
按你的看法在算术运算符周围插入空格。 始终保持二元运算符两边空格的一致。<br />
一些例子：<br />
#!Python<br />
i = i+1<br />
submitted = submitted + 1<br />
x = x*2 &#8211; 1<br />
hypot2 = x*x + y*y<br />
c = (a+b) * (a-b)<br />
c = (a + b) * (a &#8211; b)<br />
不要在用于指定关键字参数或默认参数值的&#8217;='号周围使用空格，例如：<br />
#!Python<br />
def complex(real， imag=0。0)：<br />
return magic(r=real， i=imag)<br />
不要将多条语句写在同一行上：<br />
No： if foo == &#8216;blah&#8217;：do_blah_thing()<br />
Yes：if foo == &#8216;blah&#8217;：<br />
do_blah_thing()</p>
<p>No：do_one()：do_two()：do_three()<br />
Yes： do_one()<br />
do_two()<br />
do_three()</p>
<p><strong>注释</strong><br />
同代码不一致的注释比没注释更差。当代码修改时，始终优先更新注释!注释应该是完整的句子，如果注释是一个短语或句子，首字母应该大写，除非他是一个以小写字母开头的标识符(永远不要修改标识符的大小写)。<br />
如果注释很短，最好省略末尾的句号。注释块通常由一个或多个由完整句子构成的段落组成，每个句子应该以句号结尾。你应该在句末，句号后使用两个空格，以便使Emacs的断行和填充工作协调一致。<br />
用英语书写时，断词和空格是可用的。非英语国家的Python程序员：请用英语书写你的注释，除非你120%的确信这些代码不会被不懂你的语言的人阅读。</p>
<p><strong>注释块</strong><br />
注释块通常应用于跟随着一些(或者全部)代码并和这些代码有着相同的缩进层次。注释块中每行以‘#’和一个空格开始(除非他是注释内的缩进文本)。注释块内的段落以仅含单个‘#’的行分割。注释块上下方最好有一空行包围(或上方两行下方一行，对一个新函数定义段的注释)。</p>
<p><strong>行内注释</strong><br />
一个行内注释是和语句在同一行的注释，行内注释应该谨慎适用，行内注释应该至少用两个空格和语句分开，它们应该以&#8217;#'和单个空格开始。<br />
x = x+1 # Increment x<br />
如果语意是很明了的，那么行内注释是不必要的，事实上是应该被移除的。不要这样写：<br />
x = x+1 # Increment x<br />
x = x+1 # Compensate for border<br />
但是有时，这样是有益的：<br />
x = x+1 # Compensate for border</p>
<p><strong>文档字符串</strong><br />
应该一直遵守编写好的文档字符串的约定PEP 257 [3]。为所有公共模块，函数，类和方法编写文档字符串。文档字符串对非公开的方法不是必要的，但你应该有一个描述这个方法做什么的注释。这个注释应该在”def”这行后。<br />
PEP 257 描述了好的文档字符串的约定。一定注意，多行文档字符串结尾的”"”应该单独成行，例如：<br />
“”"Return a foobang<br />
Optional plotz says to frobnicate the bizbaz first。<br />
“”"<br />
对单行的文档字符串，结尾的”"”在同一行也可以。<br />
<strong>版本注记</strong><br />
如果你要将RCS或CVS的杂项(crud)包含在你的源文件中，按如下做。<br />
#!Python<br />
__version__ = “$Revision： 1。4 $”<br />
# $Source： E：/cvsroot/Python_doc/pep8。txt，v $<br />
这个行应该包含在模块的文档字符串之后，所有代码之前，上下用一个空行分割。</p>
<p><strong>命名约定</strong><br />
Python库的命名约定有点混乱，所以我们将永远不能使之变得完全一致，不过还是有公认的命名规范的。新的模块和包(包括第三方的框架)必须符合这些标准，但对已有的库存在不同风格的，保持内部的一致性是首选的。</p>
<p><strong>描述：命名风格</strong><br />
有许多不同的命名风格。以下的有助于辨认正在使用的命名风格，独立于它们的作用。 以下的命名风格是众所周知的：<br />
b (单个小写字母)<br />
B (单个大写字母)<br />
Lowercase（小写）<br />
lower_case_with_underscores（有下划线的小写）<br />
UPPERCASE（大写）<br />
UPPER_CASE_WITH_UNDERSCORES（有下划线的大写）<br />
CapitalizedWords (或 CapWords，CamelCase这样命名是因为可从字母的大小写分出单词。这有时也被当作StudlyCaps。<br />
mixedCase (与CapitalizedWords的不同在于首字母小写!)<br />
Capitalized_Words_With_Underscores（有下划线的首字母大写） (丑陋!)<br />
还有用短的特别前缀将相关的名字聚合在一起的风格。这在Python中不常用，但是出于完整性要提一下，例如，os.stat()函数返回一个元组，他的元素传统上说名如st_mode， st_size，st_mtime等等。<br />
X11库的所有公开函数以X开头。(在Python中，这个风格通常认为是不必要的，因为属性和方法名以对象作前缀，而函数名以模块名作前缀。)<br />
另外，以下用下划线作前导或结尾的特殊形式是被公认的(这些通常可以和任何习惯组合)：<br />
_single_leading_underscore(单个下划线作前导)：弱的“内部使用(internal use)”标志。 (例如，“from M import *”不会导入以下划线开头的对象)。<br />
single_trailing_underscore_(单个下划线结尾)： 用于避免与Python关键词的冲突，例如：“Tkinter.Toplevel(master，class_=&#8217;ClassName&#8217;)”。<br />
_double_leading_underscore(双下划线)：从Python 1.4起为类私有名。<br />
_double_leading_and_trailing_underscore_：“magic”对象或属性，存在于用户控制的(user-controlled)名字空间，例如：_init_， _import_ 或_file_。有时它们被用户定义用于触发某个魔法行为(例如：运算符重载)：有时被构造器插入，以便自己使用或为了调试。因此，在未来的版本中，构造器(松散得定义为Python解释器和标准库)可能打算建立自己的魔法属性列表，用户代码通常应该限制将这种约定作为己用。欲成为构造器的一部分的用户代码可以在下滑线中结合使用短前缀，例如：<br />
_bobo_magic_attr__。</p>
<p><strong>说明：命名约定</strong><br />
应避免的名字。永远不要用字符‘l’(小写字母el(就是读音，下同))，‘O’(大写字母oh)，或‘I’(大写字母eye)作为单字符的变量名。在某些字体中这些字符不能与数字1和0分辨。试着在使用‘l’时用‘L’代替。</p>
<p><strong>模块名</strong><br />
模块应该是不含下划线的，简短的，小写的名字。因为模块名被映射到文件名，有些文件系统大小写不敏感并且截短长名字，模块名被选为相当短是重要的，这在Unix上不是问题，但当代码传到Mac或Windows上就可能是个问题了。<br />
当用C或C++编写的扩展模块有一个伴随Python模块提供高层(例如进一步的面向对象)接口时，C/C++模块有下划线前导(如：_socket)。Python包应该是不含下划线的，简短的，全小写的名字。</p>
<p><strong>类名</strong><br />
几乎不出意料，类名使用CapWords约定。内部使用的类外加一个前导下划线。</p>
<p><strong>异常名</strong><br />
如果模块对所有情况定义了单个异常，它通常被叫做“error”或“Error”。似乎内建(扩展)的模块使用“error”(例如：os.error)，而Python模块通常用“Error” (例如：xdrlib.Error)。趋势似乎是倾向使用CapWords异常名。</p>
<p><strong>全局变量名</strong><br />
(让我们祈祷这些变量仅在一个模块的内部有意义)<br />
这些约定和在函数中的一样。模块是被设计为通过“from M import *”来使用的，必须用一个下划线作全局变量(及内部函数和类)的前缀防止其被导出(exporting)。</p>
<p><strong>函数名</strong><br />
函数名应该为小写，可能用下划线风格单词以增加可读性。mixedCase仅被允许用于这种风格已经占优势的上下文(如：threading.py)，以便保持向后兼容。</p>
<p><strong>方法名和实例变量</strong><br />
这段大体上和函数相同：通常使用小写单词，必要时用下划线分隔增加可读性。仅为不打算作为类的公共界面的内部方法和实例使用一个前导下划线，Python不强制要求这样：它取决于程序员是否遵守这个约定。<br />
使用两个前导下划线以表示类私有的名字，Python将这些名字和类名连接在一起：<br />
如果类Foo有一个属性名为_a，它不能以Foo._a访问。(固执的用户还是可以通过Foo._Foo__a得到访问权。)<br />
通常双前导下划线仅被用于避免含子类的类中的属性名的名字冲突。</p>
<p><strong>继承的设计</strong><br />
始终要确定一个类中的方法和实例变量是否要被公开。通常，永远不要将数据变量公开，除非你实现的本质上只是记录，人们几乎总是更喜欢代之给出一个函数作为类的界面(Python 2.2 的一些开发者在这点上做得非常漂亮)。<br />
同样，确定你的属性是否应为私有的。私有和非私有的区别在于模板将永远不会对原有的类(导出类)有效，而后者可以。你应该在大脑中就用继承设计好了你的类，私有属性必须有两个前导下划线，无后置下划线，非公有属性必须有一个前导下划线，无后置下划线，公共属性没有前导和后置下划线，除非它们与保留字冲突，在此情况下，单个后置下划线比前置或混乱的拼写要好，例如：class_优于klass。<br />
最后一点有些争议：如果相比class_你更喜欢klass，那么这只是一致性问题。</p>
<p><strong>设计建议</strong><br />
单个元素(singletons)的比较，如None 应该永远用：‘is’或‘is not’来做。当你本意是“if x is not None”时，对写成“if x”要小心。例如当你测试一个默认为None的变量或参数是否被设置为其它值时，这个值也许在布尔上下文(Boolean context)中是false！<br />
基于类的异常总是好过基于字符串的异常。模块和包应该定义它们自己的域内特定的基异常类，基类应该是内建的Exception类的子类。还始终包含一个类的文档字符串。例如：<br />
#!Python<br />
class MessageError(Exception)：<br />
“”"Base class for errors in the email package。”"”<br />
使用字符串方法(methods)代替字符串模块，除非必须向后兼容Python 2.0以前的版本。字符串方法总是非常快，而且和unicode字符串共用同样的API(应用程序接口)在检查前缀或后缀时避免对字符串进行切片。用startswith()和endswith()代替，因为它们是明确的并且错误更少。例如：<br />
No： if foo[：3] == &#8216;bar&#8217;：<br />
Yes： if foo。startswith(&#8216;bar&#8217;)：<br />
例外是如果你的代码必须工作在Python 1.5.2 (但是我们希望它不会发生！)，对象类型的比较应该始终用isinstance()代替直接比较类型，例如：<br />
No： if type(obj) is type(1)：<br />
Yes： if isinstance(obj， int)：<br />
检查一个对象是否是字符串时，紧记它也可能是unicode字符串！在Python 2.3，str和unicode有公共的基类，basestring，所以你可以这样做：<br />
if isinstance(obj， basestring)：<br />
在Python 2.2类型模块为此定义了StringTypes类型，例如：<br />
#!Python<br />
from types import StringTypes<br />
if isinstance(obj， StringTypes)：<br />
在Python 2.0和2.1，你应该这样做：<br />
#!Python<br />
from types import StringType， UnicodeType<br />
if isinstance(obj， StringType) or \<br />
isinstance(obj， UnicodeType) ：<br />
对序列，(字符串，列表，元组)，使用空列表是false这个事实，因此“if not seq”或“if seq”比“if len(seq)”或“if not len(seq)”好。书写字符串文字时不要依赖于有意义的后置空格。这种后置空格在视觉上是不可辨别的，并且有些编辑器(特别是近来，reindent.py)会将它们修整掉。不要用==来比较布尔型的值以确定是True或False(布尔型是Pythn 2.3中新增的)<br />
No： if greeting == True：<br />
Yes： if greeting：</p>
<p>No： if greeting == True：<br />
Yes： if greeting：</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhblog.net/archives/893.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

