@Lenciel

How To Define Viewport For Mobile

概念:设备像素和CSS像素

首先要明白CSS像素和设备像素之间的区别。

设备像素是定义了我们使用的设备的分辨率,一般来说可以通过screen.width/height来得到。

如果我们在浏览器里面创建一个width:128px的元素,而我们的屏幕是1024px宽,那么在浏览器最大化的时候,浏览器的宽度应该是这个元素的八倍(大概八倍,暂时忽略那些tricky的bits)。

如果用户使用滚轮放大或者缩小页面(Zooming),那么这个关系就会变化。一般来说,现在的浏览器对Zomming的实现都是通过伸缩像素,也就是当用户Zoom到200%的时候,你的128px宽的元素宽度并不会变成256px,而是每个像素的宽度翻倍了:这个元素还是128px的宽度,但是占据了256个设备像素。

也就是说,zoom到200%其实会让一个CSS像素从一个设备像素变成四个设备像素的大小(长宽各翻一倍,面积就变成了4倍)。

         原始(zoom 100%)                 开始放大(zoom in)              开始缩小(zoom out)

csspixels_100  csspixels_in  csspixels_out

从这里可以看出,我们在使用css像素值在css文件里面定义宽度时,不需要考虑设备像素,因为在zoom的时候css像素值是不变的。用户在缩放的时候,浏览器负责放大缩小那些元素,但是整个layout是不变的。

屏幕大小

screen.widthscreen.height可以获取用户屏幕的尺寸。获得的尺寸值的单位是设备像素,换句话说,它们是不变的(可以看成是显示器的硬件指标,而不随浏览器窗口缩放而变化)。

desktop_screen

一般来说,用户的屏幕大小对我们是无用的信息。很少有人使用它(除开统计站点访问信息时)。

窗口大小

窗口大小表示了当前你的CSS layout可以占用的空间大小。可以通过window.innerWidthwindow.innerHeight来获取它们。

desktop_inner

很显然,窗口大小的单位是CSS像素值。当用户用滚轮放大缩小自己的窗口大小的时候,window.innerWidth/Height会相应的变化,这样你就知道自己的layout有多大空间可用了。

注意:Opera是一个例外,它的window.innerWidth/Height不会因为缩放变化,而是取的设备像素值。这点对于桌面操作系统上的应用很讨厌,但是就像后面会说到的,对于手机来说很关键。

Scrolling offset

window.pageXOffset/pageYOffset代表了当前的document在横向和纵向上的偏移量。这样你就知道用户scroll了多少内容。

desktop_page

这些值也是CSS像素,理论上,当用户做缩放的时候,window.pageXOffset/pageYOffset也会变化。但是实际上,浏览器一般会在用户缩放的时候保证置顶的元素不变,所以在缩放的时候,一般来说这两个值基本是不变的。

概念:Viewport

Viewport的主要作用是限定<html>元素,也就是整个页面的最高级元素的大小。这样说比较含糊,我们来看一个详尽的例子:假设你有一个页面,侧栏的宽度是10%。在你缩放浏览器窗口大小的时候,这个侧边栏也会自动缩放。这是如果实现的?

技术上讲,按照设置,侧边栏会自动占据自己的父元素(这里我们可以假设是<body>)宽度的10%。那么<body>的宽度呢?又会取它的父元素<html>的宽度的100%——因为理论上所有的HTML的block-level元素都会自动取父元素宽度的100%(有些例外情况,我们这里忽略它们)。

那么<html>的宽度是怎么来的呢?所有的网页开发者都默认它就是浏览器的宽度。的确如此——在桌面浏览器上就是这样。实际上,就像我们已经提到过的,的宽度是viewport限定的。在桌面上它就是整个浏览器窗口的宽度,而在手机上则要复杂得多。

手机浏览器

手机一个显而易见的特点就是屏幕小。如果我们原封不动的使用为桌面版浏览器开发的网站的文件,就会发现它们在手机浏览器上面目全非。但是大多数网站开发者是没有精力给手机用户专门维护另外一个网站的。因此手机浏览器制造商尽可能的通过技术手段让网站在手机上和在桌面浏览器里看起来“差不多”。

两个viewports

既然手机浏览器的viewport比较小,没法呈现所有css定义的元素,那么解决这个问题的办法就很明显了:扩大手机上的viewport。最终,手机浏览器通过visual viewportlayout viewport的合作来解决问题。

George在Stack Overflow上解释说:

layout viewport就像一个不改变大小和形状的大的图片。想象一下你透过一个小窗口去看这个大的图片,因为窗框的遮挡,你只能看到大图片的一部分。这部分就是visual viewport。你可以改变自己和这个窗口的位置(其实就是缩放),你也可以把窗口横放或者竖放,但是大图片本身(layout viewport)是不会改变的。

mobile_visualviewport

要注意,CSS layout,特别是用百分比定义的layout,都是用layout viewport来算的,一般来说比visual viewport要宽很多。

因此,起始阶段会占据整个layout viewport的宽度,你用CSS定义的元素的尺寸会比手机屏幕的尺寸要宽,这主要是要模拟网站在手机浏览器上的表现。

那么layout viewport究竟有多宽?这个要看具体的手机浏览器。Safari的iPhone版为980px,Opera是850px,Android的Webkit是800px,而IE是974px。还有一些其他的浏览器除开特别的宽度之外有特别的行为,比如Symbian上的Webkit会尽量保持layout viewport和visual viewport相同。当layout viewport超过了850px的时候,两者才会变得不同。

缩放

很明显,visual和layout两种viewport都使用了CSS像素,但是layout viewport是不会因为缩放操作变化的,而visual viewport会。很多的移动设备上的浏览器,在默认情况下都是以完全zoom-out的尺寸来显示页面的——结合前面的对两种viewport的简介,你可以认为这种时候你是把头伸到窗口(visual viewport)外在看窗外那副大图片(layout viewport),这种情况下两个viewport也是相等的(没有被窗框遮住的部分)。

因此,layout viewport的宽和高等于在完全zoom-out的情况下screen上最大可显示的CSS像素值大小。因此在随后用户如果zoom-in了这个值是不会变化的。

下面的图表示了这个变化:在刚开始打开一个页面的时候,处于完全zoom-out的状态,layout viewport的值等于visual viewport的值。随后,当用户zoom-in(放大页面)时,每个CSS像素变成数倍于设备像素,而整个layout viewport的值不变(这样才保证你为页面定义的CSS长宽有意义),于是layout viewport的物理范围扩大了不少。

mobile_viewportzoomedout                              mobile_layoutviewport

另外要注意的就是layout viewport的宽度是保持不变的。也就是说在默认情况下,竖屏转横屏的时候,虽然visual viewport变化了,但是浏览器会自动的zoom-in一些来使得layout viewport和visual viewport仍然相等。这种情况下,layout viewport的高度会变小,但是,对于web开发者而言,最重要的是宽度能保持不变。

mobile_viewportzoomedout            mobile_layoutviewport_la

测量layout viewport

document.documentElement.clientWidth/Height得到的是layout viewport的数值。并且,如前所述,横竖屏转换时,只会影响Height不会影响Width取值。

document.documentElement.clientWidht/Height

  • Layout viewport
  • 使用CSS像素值为单位
  • 支持Opera、iPhone、Android、Symbian、Bolt、MicroB、Skyfire和Obigo
  • 有一些问题:

  • Samsung的Webkit的viewport只有当显式指定了的时候才有效,否则返回的是元素的长宽

  • Firefox返回的是以设备像素值为单位的结果

  • IE返回1024×768,正确的信息要通过document.body.clientWidth/Height获取

测量visual viewport

window.innerHeight/Width返回的是visual viewport。很显然,当用户缩放的时候,这两个值会变化,因为有更多或者更少的CSS像素适配到屏幕可见的部分中。

window.innerHeight/Width

  • visual viewport
  • 使用CSS像素值为单位
  • 支持iPhone、Symbian、BlackBerry
  • 有一些问题:

  • Samsung的Webkit返回的是layout viewport的取值只有当显式指定了的时候才有效,否则返回的是元素的长宽

  • Firefox和Opera返回的是以设备像素值为单位的结果

  • IE不支持,正确的信息要通过document.documentElement.offsetWidth/Height获取

  • 其他的如Iris、Skyfire或者Obigo是有返回值到乱来的

手机屏幕大小

前面提到过,在桌面系统,screen.width/hieght返回屏幕的大小,但是和桌面系统一样,开发者都不关心这个值:因为物理上屏幕多大并不重要,我们更关心多少个CSS像素能弄进这个屏幕。

元素

通过document.documentElement.offsetWidth/Height可以获取<html>元素的CSS像素单位的尺寸。

缩放比例

当screen.width和window.innerWidth在你工作的平台都得到了正确实现的时候,两者相除就可以得到缩放的比例大小。

Media query

Media query的思想就是定义只在页面大于,等于或者是小于一定尺寸的时候,才被执行的CSS规则。比如:

1
2
3
4
5
6
7
8
9
10
11
div.sidebar {
    width: 300px;
}

@media all and (max-width: 400px) {
    // styles assigned when width is smaller than 400px;
    div.sidebar {
        width: 100px;
    }

}

规则指定了当宽度小于400px的时候sidebar是100px,其余时候是300px。

需要注意的是在定义media query的时候可以用两套长宽:css里的width/height表示的是documentElement. clientWidth/Height取值,也就是viewport,单位是css像素。css里的device-width/height表示的是screen.width/height,单位是物理像素。

那么使用哪种值来定义media query甚至用不用它都是让人疑惑的问题。比如你用device-width的话 ,其实效果和使用来定义是类似的。但是用width,仅仅是一个模糊的像素宽度,更加缺乏在各种设备上具体效果的准确预期。目前来看,用media query应该能比较正确的区分运行环境是桌面,手机还是平板,但是并不太能细致到是那款平板或者是什么手机。

Meta viewport

终于可以来讨论了。这个最早是Apple的一个扩展,但是现在已经被各种浏览器抄去了。它主要的作用是用来重定义layout viewport的大小。

我们通过实例来解释:假设你开发了一个网站,没有写css,因此所有的元素没有width属性。打开页面的时候,它们会默认zoom-out到最大,看起来像这样:

mq_none

用户肯定会zoom-in,这时因为很多浏览器会保持每个元素的宽度仍然是100%的layout viewport,因此,很多文字就撑到visual viewport外面去了变得不可见了(Android原生的Webkit在这种情况下会自动调整text-containing元素的宽度来适配屏幕宽度)。

mq_none_zoomed

为了避免这种情况,你可能会加上html {width:320px}的css规则。这样的宽度,也就是大多数未定义宽度的元素继承到的宽度,是320px。这样的规则可以解决用户zoom-in放大页面之后溢出的问题,但是当用户刚打开页面的时候,大概又会看的下图的效果(因为300个CSS像素值在完全zoom-out的情况下是很窄的):

mq_html300

为了解决这种初始和用户缩放之后的不和谐,Apple定义了一个新的meta值。你可以用

1
<meta name="viewport" content="width=320"/>

来确定layout viewport的宽度。这样在初始的时候,整个页面看起来仍然是非常正确的:

mq_yes

meta中定义的layout viewport宽度甚至可以是device-width,也就是以设备像素值标定的screen.width取值。但是这里有一个陷阱,就是有时候正式的screen.width的取值并不是真的有实际意义,因为像素值可能太高。比如Nexus One的屏幕宽度是480px,但是Google的工程师觉得用device-width来定义viewport就让layout viewport取值480px太宽了,于是它们让device-width的返回值打了个2/3的折扣,只有320px,和iphone一致。这样一来,device-width的取值又有点儿CSS像素值的意思了。这种resolution标称的像素值和device-width的返回值之间的关系被称为CSS pixel density

Device resolution (px) device-width/ device-height (px)
iPhone 320 x 480 320 x 480, portrait/landscape mode
iPhone 4 640 x 960

320 x 480, in both portrait and landscape mode

CSS pixel density  = 2

iPad 1 and 2 768 x 1024 768 x 1024, portrait/landscape mode
new iPad 1536 x 2048

768 x 1024, portrait/landscape mode

CSS pixel density = 2

Samsung Galaxy S I and II 480 x 800

320 x 533, portrait mode

CSS pixel density = 1.5

Samsung Galaxy S III 720 x 1280 360? x 640?, portrait mode
HTC Evo 3D 540 x 960

360 x 640, portrait mode

CSS pixel density = 1.5

Amazon Kindle Fire 1024 x 600 1024 x 600, landscape mode

Getting Start With Python

刚刚开始使用Python开发的新手,遇到的第一个瓶颈(常常)就是缺乏对整个Python生态系统的理解。大家总是在网上搜索完成这件事或者那件事的“标准做法”,就像我们使用其他编程语言的时候常常需要掌握的一样。

在和几个朋友开始iDVR的开发的时候,我们在内部Wiki上维护过一个Python中常见问题列表。我们的目标是随着项目的不断进步,这个内部的wiki能够变成一个豪华的Q&A索引,但是事实证明项目一忙起来就没有人去写Wiki了。

最近陆续有朋友问一些Python相关的问题,想想其实要用三言两语说清楚并不容易,就决定在那份wiki的基础上自己写一个版本,给那些刚开始使用Python(从来没有编过程的读起来可能没啥帮助)的同学。

Warning

Python编程是个大话题,不是这里讨论的内容。如果你没有太多编程经验,应该先去看一点儿Python的入门书籍

另外,这片文章是基于Windows(最好是Win7 32bit)操作系统。潮人请不要问为啥不是Mac或者Linux,因为本座主要用的机器(包括码这篇Blog)都是用Win7 32bit。不过除开环境搭建,这里提到的大部分概念对其他系统都是适用的。

如果你有环境搭建上的问题,最靠谱的提问的地方不是CSDN或者百度知道,是Stack Overflow

版本选择

本座在某软件公司面试的时候别人看到简历上有Python就问,Python3用过吗?本座老实回答没有,结果面试官就停下他正在笔记本上google的微操,在脸上流露出一丝嘲讽…

不过,除了Python这门语言本身的开发者,大多数像本座这种使用Python的人,都没有紧跟Python3的步伐。Python3(或者叫Py3K)是一个大多数我熟悉的包,框架和工具都还没有完备支持的版本(在未来的数年本座也看不到希望)。如果不是想研究Python3的新特性或者具体实现,个人觉得初学的开发者使用2.7.x是最安全的版本(本座还在用进M公司就装好的2.6版本)。

如果你比较熟悉Python但是不确定该不该升级到Python3,不妨先去观赏一下Python 3 Wall of Shame (墙外,你们懂的)。

VM选择

Python是脚本语言,因此需要VM。CPython是最主流的选择,也被当成其他VM实现时的参考。其他常见的还有用Python实现的PyPy,用Java实现的Jython 以及用Microsoft .Net CLR实现的IronPython。如果你不是非常非常确定你自己要选用别的,就安装CPython吧。

换句话说,前面这堆关于VM和版本选择的建议在你看来不知所云,你需要的就是CPython 2.7.x版本

Python安装

下载之后的.exe安装文件安装的时候有一个地方需要注意:如果你是在Vista/Win7这样的C盘权限控制异常严格的操作系统,最好用右键“Run as administrator”。这点也适用于你下载到的被其他人编译成exe发布的Python package。嗯,什么是package?

理解Package

Python没有一个内置的package管理体系。实际上Python下面一个package是什么也是一个很“不具体”的概念。就像前面提到的,Python下面的代码是以module为单位存在的。每个module既可以是一个只有一个函数的文件,也可以是一个包含了一个或者多个子module的目录。而module和package之间的区别是非常模糊的,每个module都可以被认为是一个package。

和所有的编程环境一样,在Python下面有一些函数和类是全局可见的(strlenException等等),而另外一些需要通过import语句导入,比如:

1
2
>>>import os
>>>from os.path import basename, dirname

这里import被调用的时候,Python是从哪里把这些module导入的呢?其实,在你安装Python的时候,module的导入路径已经被自动设置过了。这个过程的具体实现是跟你运行的平台相关的,你可以通过sys.path来查看被设置的路径究竟是什么。比如本座的是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
['',
'C:\\Python26\\lib\\site-packages\\demjson-1.4-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\anyjson-0.2.5-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\pmw-1.3.2-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\paramiko-1.7.6-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\treewidgets-1.0a1-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\mechanize-0.2.3-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\pylint-0.22.0-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\logilab_astng-0.21.0-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\logilab_common-0.53.0-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\unittest2-0.5.1-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\virtualenv-1.5.1-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\django_staticfiles-0.3.2-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\django_attachments-0.3dev-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\django_ajax_validation-0.1.4-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\django_email_confirmation-0.2.dev4-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\distribute-0.6.10-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\django_timezones-0.2.dev1-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\django-1.3-py2.6.egg',
'C:\ \Python26\\lib\\site-packages\\rbtools-0.3.2-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\django_debug_toolbar-0.8.4-py2.6.egg',
'C:\\Python26\\lib\\site-packages\\suds-0.4-py2.6.egg',
'C:\\Windows\\system32\\python26.zip',
'C:\\Python26\\DLLs',
'C:\\Python26\\lib',
'C:\\Python26\\lib\\plat-win',
'C:\\Python26\\lib\\lib-tk',
'C:\\Python26',
'C:\\Python26\\lib\\site-packages',
'C:\\Python26\\lib\\site-packages\\PIL',
'C:\\Python26\\lib\\site-packages\\wx-2.8-msw-unicode']

Python在导入的module的时候,是按照这个列表“自顶向下,见好就收”的方式运作的。也就是说如果你正好机器上有两个路径下面安装了同样名称的module,先被搜索到的那个就会被导入。有的时候,你确信自己受到了这种机制的干扰,也可以通过下面的办法来hack回来:

1
sys.path.insert(, 'path\\to\\your\\packages')

进行一段时间的Python开发过后你总是会有很多的包,于是这个办法你会觉得非常的方便。但是,请结合后面的内容默默记住,不到万不得已,不要这样hack。

The PYTHONPATH

PYTHONPATH是一个环境变量(可以win+break到高级设置里面去设置),可以简单的理解它就是Windows下面的PATH变量,不过只是对Python可见而已。在很多Python的教程里面,会说所有你想要让Python搜索module的路径,都应该加到这个变量对应的列表里面。

其实前面提到过,在Python安装的时候搜索路径已经被自动设置过一次。所以PYTHONPATH这个变量并不是必须加的。而且,作为开发环境满坑满谷的程序员,我们都喜欢把Path里面搞得干干净净的(比如本座干活都习惯在bat里面先设置相关的路径再起相应的Eclipse)。这种一启动就load一堆的办法,自己喜欢也可以用,但是更推荐后面会说的virtualenv

第三方package

首先,入门之后要开始正经干活,你总是需要安装一些第三方的Package。安装的办法有:

  1. 下载别人编译好的Windows的版本exe
  2. 使用pip或者easy_install
  3. 自己从代码安装

三种办法干的事情都是类似的:下载package的依赖包,编译(需要的话)和拷贝目标文件到一个默认的第三方Package路径。那么,哪里去找安装需要的文件呢?一般来说:

  1. Google
  2. Python Package Index(or PyPI)
  3. 各种开源的代码库(Launchpad/GitHub/BitBucket
安装别人编译好的exe

注意下载的时候看清别人编译是在32还是64bit的Windows,Python的版本和你用的一致不一致。运行exe的时候注意右键Run as Administrator。就这么简单。

使用pip

easy_install已经慢慢失宠了,主要介绍一下它的替代品:pip

pip是用来安装和管理Python Package的工具。它不是随Python默认安装的,因此需要额外安装。安装完毕之后我们就可以在命令行里面调用它来管理package了。比如你要安装pygame这个package,只需要:

pip install pygame

而如果你想删除它的话,则运行:

1
pip uninstall pygame

pip默认会按照你指定的名字,搜索和安装最新的stable版本的包。但我们常常需要安装某个特定版本的包,这个时候需要你在命令行里面指定:

1
pip install pygame==version_number

如果你安装的版本不对,可以通过upgrade命令升级/降级到指定版本:

1
pip install pygame==version_number –upgrade

由于Python高度依赖开源团体,很多最新的package都没有在PyPI上面,我们常常需要从代码库直接安装package。在pip下面可以直接

1
2
3
$ pip install git+http://somedomain.com/path/to/git-repo#egg=packagename
$ pip install hg+http://somedomain.com/path/to/hg-repo#egg=packagename
$ pip install svn+http://somedomain.com/path/to/svn-repo#egg=packagename

当然,前提是git/hg/svn这些工具你都安装好了并且在命令行里面能够执行。

上面这些egg是什么蛋呢?你可以认为它们就是Package源代码和一些metadata打成的压缩包。pip会读取egg里面的setup.py文件,然后安装egg到你的文件系统。

从Python源码安装

从源代码安装虽然是最复杂的,但是也没那么复杂。把你下载的源代码解压之后,找到setup.py所在的路径,然后运行下面的命令:

1
python setup.py install

也许你觉得这样也挺容易的,为啥要去用pip?因为:

  • 省去你上网找源代码,解压,安装这些动作
  • 更重要的是,pip不但装,而且管。你可以升级和降级一个Package。
安装需要编译的package

这种一般是因为Package里面有c/cpp的代码。如果你能找到别人编译好的exe文件或者用pip,最好不要自己折腾。只有非常非常罕见的情况下你需要自己编译,过程中一般来说都会需要用cygwin之类的东西,在前面几次你可以多看看每个Package的readme关于编译的说明。

开发环境

virtualenv

virtualenv无疑是当前Python开发者心中“必知必会”类的工具了。virtualenv主要就是提供一个“独立的”Python开发环境。为什么需要“独立”的开发环境?在不知道virtualenv之前Python包满坑满谷的本座自然是有很多槽可以吐,不过最好的答案是virtualenv的文档里面说的:

The basic problem being addressed is one of dependencies and versions, and indirectly permissions. Imagine you have an application that needs version 1 of LibFoo, but another application requires version 2. How can you use both these applications? If you install everything into /usr/lib/python2.7/site-packages (or whatever your platform’s standard location is), it’s easy to end up in a situation where you unintentionally upgrade an application that shouldn’t be upgraded.

简单来说,就是每个工程使用自己独立的virtualenv进行开发,所有该工程需要依赖的Package都安装在这个virutalenv里面。virutalenv的安装同样是使用pip

1
$ pip install virtualenv

然后就可以建立属于自己项目的开发环境:

1
2
3
4
5
6
D:\Lenciel\Temp mkdir my_project_env

D:\Lenciel\Temp\virtualenv --distribute my_project_env

  New python executable in my_project_env\Scripts\python.exe
  Installing distribute.................done.

建立的目录下面会自动的安装好pip等工具:

1
2
3
-my_project_env
  |-- Scripts # -- Python解释器的拷贝/pip脚本/activiate脚本/deactivate脚本等
  |-- Lib     # -- 所有库(包括激活后使用pip安装的库都会放在这里

在命令行执行activate脚本就可以激活你新建的环境。环境被激活后,主要通过下面两个功能保持独立完整性:

  1. 当你在被激活的环境里面使用pip安装一个Package的时候,它只会被安装在这个工作目录下面
  2. 当你import的时候,会先从工作目录下面去搜索,然后才会搜索系统目录下的

需要注意的是,在系统目录下面安装的包,对所有的virtualenv建立的环境都是可见的。如果你不想在你建立的virtualenv里面看到这些包,可以使用--no-site-packages参数建立开发环境:

1
$ virtualenv my_project_venv --no-site-packages

其他的工具

编辑器

在不同的项目里面本座用过Vim/Sublime text 2/Eclipse+PyDev/PyCharm。现在Vim和PyCharm用得比较多一点,PyDev一直有一些诡异的问题。比如那个“Unresolved import”从一开始到现在都好像没有被真正解决过。

编码规范

PEP 0008推荐了非常完整的一套编码规范,目的就是让全世界编写Python脚本的同学们用相同的方式去对齐代码,命名变量、类和函数。每个严肃的Pythoner都应该认真的学习和理解这些规范,并且贯彻执行。

Python标准库

Python的标准库提供了相当完备的功能。就像Java的工程师需要熟悉系统自带的API文档一样,了解标准库的用法是非常有好处的。另外,这些标准库都是很好的范例,特别是在支持跨平台使用这方面。

官方文档在这里

嗯哼

前面列了不少东西,只是希望给新手一个上路指引。Python下面有用的工具,有趣的包很多很多。随着你学习和应用这门语言,不断深入它,你会自己慢慢发觉那些你自己最需要/愿意熟悉的部分。

Python的另外一大财富就是它的开源社区,条件成熟的时候,你也应该参与到这样的开发活动里面去。

最后是每个Pythoner都津津乐道的Zen Of Python送给刚开始学习的朋友。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
>>>import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Happy Pythoning…!!