3.1 语句和语法
# 表示注释
\n 表示换行符
\ 表示继续上一行
; 将两个语句连接在一行
: 将代码块的头和体分开
语句(代码块)用缩进块的方式体现
不同的缩进深度分隔不同的代码块
Python文件以模块的形式组织
3.1.1 注释(#)
顾名思义
3.1.2 继续(\)
同shell的换行连接符
if (a == 1) and \
(b == 2):
print a,b
注:在含有小括号,中括号,花括号,三引号时不使用\也可以多行书写
3.1.3 多个语句构成代码组(:):
缩进相同的一组语句构成一个代码组,我们称之代码组
例如: if,while,def,class的符合语句,首行以关键字开始,以冒号:结束,改行之后的一行或多行代码构成代码组.
我们将首行及后面的代码组成为一个子句(clause)
3.1.4 代码组由不同的缩进分隔
使用4个空格作为一个代码组,避免使用制表符
3.1.5 同一行书写多个语句;
import sys; x = 'foo'; sys.stdout.write(x + '\n')
不推荐
3.1.6 模块
每一脚本文件,一段执行脚本,一段库文件代码都可组成一个模块
3.2 变量赋值
赋值运算符 =
注:赋值并不是直接将一个值赋给一个变量的
Python语言中,对象是通过引用传递的,在赋值时,不管这个对象是新创建的,还是一个已经存在的,都是将该对象的引用(并不是值)赋值给变量
Python赋值语句不会返回值
>>> x = 1
>>> y = (x = x + 1)
File "<stdin>", line 1
y = (x = x + 1)
^
SyntaxError: invalid syntax
链式赋值没问题
>>> x = 1
>>> y = x = x + 1
>>> x,y
(2, 2)
增量赋值
x = x + 1 或 x += 1
>>> m = 12
>>> m %= 7
>>> m
5
>>> m **=2
>>> m
25
>>> aList = [123,'xyz']
>>> aList += [45.6e7]
>>> aList
[123, 'xyz', 456000000.0]
注:Python不支持类似x++或--x这样的前置/后置自增/自减运算
多重赋值
>>> x = y = z =1
>>> x
1
>>> y
1
>>> z
1
"多元"赋值
采用这种方式赋值时,等号两边的对象都是元祖
>>> x,y,z = 1,2,'a string'
>>> x
1
>>> y
2
>>> z
'a string'
建议这么写
>>> (x,y,z) = (1,2,'a string')
C语言交换变量需要用一个临时变量tmp来保存其中一个值
例:
tmp=x;
x=y;
y=tmp;
Python的多元赋值可以实现无需中间变量即可交换两个变量的值
>>> x,y =1,2
>>> x
1
>>> y
2
>>> x,y =y,x
>>> x
2
>>> y
1
3.3 标识符
标识符是电脑语言中允许作为名字的有效字符串集合,有一部分是关键字,关键字不能作为标识符,否则会引起语法错误(SyntaxError 异常)
3.3.1 合法的Python标识符
(1) 第一个字符必须是字母或下划线_
(2) 剩下的字符可以是字母和数字或下划线
(3) 大小写敏感
3.3.2 关键字
关键字列表和iskeyword()函数都放入了keyword模块一边查阅
3.3.3 内建
built-in是__builttins__模块的成员,在程序开始或交互解释器>>>进入前,已由解释器自动导入,视为Python的全局变量
3.3.4 专用下划线标识符
_xxx 不用'from module import x'导入
__xxx__ 系统定义名称
__xxx 类中的私有变量名
注:避免使用下划线作为变量名的开始,因为_xxx被看成是私有的,在模块或类外不可以使用
3.4 基本风格指南
注释
确保注释的准确性
文档
可以通过__doc__特别变量,动态获得文档字串
缩进
推荐四个空格作为一层代码的缩进,跨平台使用不要使用TAB做缩进
选择标识符名称
言简意赅
3.4.1 模块结构和布局
(1)起始行
仅在类Unix环境下才使用起始行,可仅输入脚本名字来执行脚本,无需直接调用解释器
(2)模块文档
介绍模块功能及重要全局变量含义,模块外可通过module.__doc__访问这些内容
(3)模块导入
导入当前模块的代码需要的所有模块:
(4)变量定义
除非必须,尽量使用局部变量代替全局变量
(5)类定义语句
所有类都需要在这里定义,当模块被导入时class语句会被执行,类也就会被定义,类的文档变量时class.__doc__
(6)函数定义语句
此处定义的函数可以通过module.function()在外部被访问到,当模块被导入时def语句被执行,函数也就会定义好,函数文档的变量是function.__doc__
(7)主程序
无论这个模块是被别的模块导入还是作为脚本直接执行,都会执行这部分代码
例:
-------------------------------------
#!/usr/bin/env python #(1)起始行
"this is a test module" #(2)模块文档
import sys
import os #(3)模块导入
debug = True #(4)(全局)变量
class FooClass(object):
"Foo class" #(5)类定义语句
def test():
"test function"
foo = FooClass()
if debug:
print 'ran test()' #(6)函数定义语句
if __name__ == '__main__':
test() #(7)主程序
--------------------------------------
注:
推荐代码风格:主程序调用main()函数
如果模块是被导入,__name__的值为模块名字
如果模块是被直接执行,__name__的值为'__mail__'
3.4.2 在主程序中书写测试代码
3.5 内存管理
变量无需事先声明
变量无需指定类型
程序员不用关心内存管理
变量名会被"回收"
del 语句能够直接释放资源
3.5.1 变量定义
变量无需声明,也无需放到代码块最开始
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
变量一旦被复制,就可以通过变量名来访问它
>>> x = 4
>>> y = 'this is a string'
>>> x
4
>>> y
'this is a string'
3.5.2 动态类型
3.5.3 内存分配
3.5.4 引用计数
要保持追踪内存中的对象,Python使用了引用计数这一简单计数,当对象被创建,就创建了一个引用计数,当这个对象不再需要时,这个对象引用变为0,而后被垃圾回收
增加引用计数
当对象被创建并赋值给变量,该对象的引用计数就设为1
例:
x = 3.14 # 3.14作为对象被引用+1
y = x # 引用+2
foobar(x) # 作为参数传递给函数 引用+3
myList = [123,x,'xyz'] # 作为容器对象的一个元素 引用+4
减少引用计数
当变量被赋值给另外一个对象时,原对象的引用计数-1
foo = 'xyz' # 引用+1
bar = foo # 引用+2
foo = 123 # 引用-1
当使用del语句删除一个变量,引用计数-1
del bar # 引用-1
对象被从一个窗口对象中移除,引用计数-1
myList.remove(x)
窗口对象本身被销毁
del myList
3.5.5 垃圾收集
不再被使用的内存会被一种称为垃圾回收的机制释放,垃圾回收器作为一块独立代码用来释放内存,不仅用来寻找引用计数为0的对象,还负责引用计数大于0但也应该被销毁的对象
3.6 第一个Python程序
例3.1
# vi makeTextFile.py
-------------------------------------
#!/usr/bin/env python
'make TextFile.py -- create text file'
import os
ls = os.linesep
# get filename
while True:
if os.path.exists('fname.txt'):
print "ERROR: '%s' already exists" %fname
else:
break
# get file content (text) lines
all =[]
print "\nEnter lines ('.' by itself to quit)\n"
#loop until user terminates input
while True:
entry = raw_input(">")
if entry == '.':
break
else:
all.append(entry)
#write lines to file with proper line_ending
fobj = open('fname.txt','w')
fobj.writelines(['%s%s' %(x,ls) for x in all])
fobj.close()
print 'DONE!'
-------------------------------------
例3.2
# vi readTextFile.py
-----------------------------------------
#!/usr/bin/env python
'readTextFile.py -- read and display text file'
# get filename
fname = raw_input('Enter filename:')
# attempt to open file for reading
try:
fobj = open(fname,'r')
except IOError,e:
print "*** file open error: ", e
else:
# display contents to the screen
for eachLine in fobj:
print eachLine,
fobj.close()
-----------------------------------------
3.6 相关模块和开发工具
Debugger: pdb
Logger: logging
Profilers: profile,hotshot,cProfile