记得数年前还在大学的时候, 刚进入机器人实验室, 石队长说:
你们要想和商*(硬件组组长)有共同语言, 至少先学好C语言, 要想和陈*(软件组组长)有共同语言, 至少先学好C++.
这几句话我至今难忘, 有时会默默的往妹子身上想… 言归正传, Raspbian 的主流开发语言有 C 和 Python(当然作为一个Linux操作系统, 用Java, Go什么的也不在话下, 只不过有些小众罢了). 为了和广大树莓派爱好者有共同语言, 先来学下Python吧.
Python官方文档(Documentation)看 这里, 中译版本看 Python 官方文档中文站 或者 Python 中文学习大本营. 官方教程(Tutorial)看 这里, 中译版本看 Python 2.7.8中译版 或者 Python 2.7.11中译版 本文的目录编法尽量与官方的入门教程目录(Python Tutorial Release 2.7.11)保持一致, 摘录整理出常用的知识点给我自己看, 过客直接看官方文档就行, 也就100来页, 半天功夫就能看完.
1. 开胃菜
用 Python 编写的程序通常比同样的 C、C++ 或 Java 程序更短小,这是因为以下几个原因:
①高级数据结构使你可以在一条语句中表达复杂的操作;
②语句组使用缩进代替开始和结束大括号来组织;
③变量或参数无需声明。
Python不像C等, 计算很长的数也不会溢出???
2. Python解释器
Mac默认安装了Python, 目录 /usr/local/bin/python
.
终端输入 python --version
可以查看当前版本号.
输入python
可以启动python.
类BSD的Unix系统, 可以将Python脚本变成可执行的, 通过放置一行:
#! /usr/bin/python
在Python源文件中可以使用非 ASCII 编码。最好的方法是在 #! 行的后面再增加一行特殊的注释来定义源文件的编码:
# -*- coding: encoding -*-
有了这个声明, 源文件的所有字符会以encoding的编码对待.
为了不反人类, 我们使用utf-8编码:
# -*- coding: utf-8 -*-
有了这行, 写中文不会再报错.
3. Python简介
# 行注释
” ” ” ” ” ” 块注释
/ 与C中的/相似, 都是int型 ,返回int型, 有一个是float型, 返回float型.
// floor 除法, 总会返回int型, 17 // 3.0
返回5
, 余数可用%求得
** 计算幂5**3
, 返回125
.
带有后缀 j 或 J 就被视为虚数。带有非零实部的复数写为 (real+imagj) ,或者可以用 complex(real, imag) 函数创建。
复数的实部和虚部总是记为两个浮点数。要从复数 z 中提取实部和虚部,使用 z.real 和 z.imag:
’ ’ 或” ” 字符串, 可混合使用.
用\
表示转义引号如换行\n
, 用+
连接字符串, 用*
表示重复. 用r
表示原始字符串, 不会被转义, 如 print 'C:\some\name'
中的\n会被认为换行, 前面加个r print r'C:\some\name'
就不会被转义了.
字符串也可以被截取(检索)。类似于 C ,字符串的第一个字符索引为 0 , 索引为负数,从右边开始计算。
字符串还支持 切片。索引用于获得单个字符,切片让你获得一个子字符串, 注意左含右不含, :
取到边.
len() 函数返回字符串长度.
Unicode 对象, 用于存储和维护 Unicode 数据 .
Unicode 的先进之处在于为每一种现代或古代使用的文字系统中出现的每一个字符都提供了统一的序列号。之前,文字系统中的字符只能有 256 种可能的顺序, 通过代码页分界映射, 文本绑定到映射文字系统的代码页。这在软件国际化的时候尤其麻烦(通常写作 i18n —— ‘i’ + 18 个字符 + ‘n’)。Unicode 解决了为所有的文字系统设置一个独立代码页的难题。
如 >>> u'Hello\u0020World !'
返回 u'Hello World !'
,转码序列 \u0020 表示在指定位置插入编码为 0x0020 的 Unicode 字符(空格)。当然, 与字符串一样, 配合r
使用, ur
会返回原始字符.
list (列表) ,它可以写作中括号之间的一列逗号分隔的值, 列表的元素不必是同一类型.
不像 不可变的 字符串,列表允许修改元素.
可以使用 append() 方法或 +
在列表的末尾添加新的元素.
内置函数 len() 同样适用于列表.
允许嵌套列表(创建一个包含其它列表的列表).
>>> i = 256*256
>>> print 'The value of i is', i
The value of i is 65536
用一个逗号结尾就可以禁止输出换行.
一个经典的输出斐波那契序列的程序:
>>> a, b = 0, 1
>>> while b < 1000:
... print b,
... a, b = b, a+b
...
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
两个注意事项:
①因为 ** 的优先级高于 -,所以 -3**2 将解释为 -(3**2) 且结果为 -9。为了避免这点并得到 9,你可以使用 (-3)**2。
②特殊字符例如 \n 在单引号(‘…’)和双引号(“…”)中具有相同的含义。两者唯一的区别是在单引号中,你不需要转义 ” (但你必须转义 \’ ),反之亦然。
4. 深入 Python 流程控制
if语句
( if … elif … elif … 序列用于替代其它语言中的 switch 或 case 语句 )
>>> x = int(raw_input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
... x = 0
... print 'Negative changed to zero'
... elif x == 0: #else是可选的
... print 'Zero'
... elif x == 1:
... print 'Single'
... else: #else是可选的
... print 'More'
for语句
>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
... print w, len(w)
...
cat 3
window 6
defenestrate 12
range() 函数
>>> range(5, 10)
[5, 6, 7, 8, 9]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(-10, -100, -30)
[-10, -40, -70]
需要迭代链表索引的话,如下所示结合使用 range() 和 len():
>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
... print i, a[i]
...
0 Mary
1 had
2 a
3 little
4 lamb
break 和 continue 语句, 以及循环中的 else 子句
break 语句和 C 中的类似,用于跳出最近的一级 for 或 while 循环。
循环可以有一个 else 子句;它在循环迭代完整个列表 (对于 for) 后或执行条件为 false (对于 while) 时执行,但循环被 break 中止的情况下不会执行:
>>> for n in range(2, 10):
... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
与循环一起使用时,else 子句与 try 语句的 else 子句比与 if 语句的具有更多的共同点:try 语句的 else 子句在未出现异常时运行,循环的 else 子句在未出现 break 时运行。更多关于 try 语句和异常的内容,请参见 异常处理。
continue 语句是从 C 中借鉴来的,它表示循环继续执行下一次迭代.
pass 语句什么也不做。它用于那些语法上必须要有什么语句,但程序什么也不做的场合:
>>> while True:
... pass # Busy-wait for keyboard interrupt (Ctrl+C)
通常用于创建最小结构的类:
>>> class MyEmptyClass:
... pass
另一方面,pass 可以在创建新代码时用来做函数或控制体的占位符。可以让你在更抽象的级别上思考。pass 可以默默地被忽视:
>>> def initlog(*args):
... pass # Remember to implement this!
关键字 def 引入了一个函数 定义 。在其后必须跟有函数名和包括形式参数的圆括号:
>>> def fib(n): # write Fibonacci series up to n
... """Print a Fibonacci series up to n."""
... a, b = 0, 1
... while a < n:
... print a,
... a, b = b, a+b
...
>>> # Now call the function we just defined:
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
函数体的第一行语句可以是可选的字符串文本,这个字符串是函数的文档字符串,或者称为 docstring 。(更多关于 docstrings 的信息请参考 文档字符串 ) 有些工具通过 docstrings 自动生成在线的或可打印的文档,或者让用户通过代码交互浏览.
函数 调用 会为函数局部变量生成一个新的符号表。确切地说,所有函数中的变量赋值都是将值存储在局部符号表。变量引用首先在局部符号表中查找,然后是包含函数的局部符号表,然后是全局符号表,最后是内置名字表。因此,全局变量不能在函数中直接赋值 (除非用 global 语句命名),尽管他们可以被引用。
以下示例演示了如何从函数中返回一个包含菲波那契数列的数值链表,而不是打印它:
>>> def fib2(n): # return Fibonacci series up to n
... """Return a list containing the Fibonacci series up to n."""
... result = []
... a, b = 0, 1
... while a < n:
... result.append(a) # see below
... a, b = b, a+b
... return result
...
>>> f100 = fib2(100) # call it
>>> f100 # write the result
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
最常用的一种形式是为一个或多个参数指定默认值。这会创建一个可以使用比定义时允许的参数更少的参数调用的函数:
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
while True:
ok = raw_input(prompt)
if ok in ('y', 'ye', 'yes'):
return True
if ok in ('n', 'no', 'nop', 'nope'):
return False
retries = retries - 1
if retries < 0:
raise IOError('refusenik user')
print complaint
这个函数可以通过几种不同的方式调用:
只给出必要的参数: ask_ok('Do you really want to quit?')
给出一个可选的参数: ask_ok('OK to overwrite the file?', 2)
或者给出所有的参数: ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')
这个例子还介绍了 in 关键字。它测定序列中是否包含某个确定的值。
重要警告: 默认值只被赋值一次。这使得当默认值是可变对象时会有所不同,比如列表、字典或者大多数类的实例。
函数可以通过 关键字参数 的形式来调用,形如 keyword = value:
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print "-- This parrot wouldn't", action,
print "if you put", voltage, "volts through it."
print "-- Lovely plumage, the", type
print "-- It's", state, "!"
接受一个必选参数( voltage )以及三个可选参数( state, action, 和 type )。可以用以下的任一方法调用:
parrot(1000) # 1 positional argument
parrot(voltage=1000) # 1 keyword argument
parrot(voltage=1000000, action='VOOOOOM') # 2 keyword arguments
parrot(action='VOOOOOM', voltage=1000000) # 2 keyword arguments
parrot('a million', 'bereft of life', 'jump') # 3 positional arguments
parrot('a thousand', state='pushing up the daisies') # 1 positional, 1 keyword
函数的更多用法参考官方文档吧, 不摘录了…
编码风格
使用 4 空格缩进,而非 TAB。
在小缩进(可以嵌套更深)和大缩进(更易读)之间,4 空格是一个很好的折中。TAB 引发了一些混乱,最好弃用。
折行以确保其不会超过 79 个字符。
这有助于小显示器用户阅读,也可以让大显示器能并排显示几个代码文件。
使用空行分隔函数和类,以及函数中的大块代码。
可能的话,注释独占一行
使用文档字符串
把空格放到操作符两边,以及逗号后面,但是括号里侧不加空格:a = f(1, 2) + g(3, 4)。
统一函数和类命名。
推荐类名用 驼峰命名,函数和方法名用 小写_和_下划线。总是用 self 作为方法的第一个参数(关于类和方法的知识详见 初识类)。
不要使用花哨的编码,如果你的代码的目的是要在国际化 环境。Python 的默认情况下,UTF-8,甚至普通的 ASCII 总是工作的最好。
同样,也不要使用非 ASCII 字符的标识符,除非是不同语种的会阅读或者维护代码。