本章介绍基本的Python语法、编程风格;并简要介绍标识符、变量和关键字,以及变量占用内存的分配和回收;最后给出一个较大的Python样例程序来体验这些特性。

1 语句和语法

1.1 注释

  可以在一行的任何位置,以 # 开头,直至行尾都是注释。

1.2 反斜线继续上一行

  一行过长的语句,可以用反斜线 \ 分解成几行。\ 必须是该行的最后一个字符(其后不能有空格等其他任何字符)。

  闭合符号:小括号()、中括号[]、花括号{}、三引号"""  """/'''  ''',其内的语句可以跨行书写,不需使用 \ 。

1.3 多个语句构成代码组

  缩进相同的一组语句构成一个代码块,称为代码组。例如:if、while等关键字开头的首行,之后的一行或多行就是一个代码组。首行及之后的代码组称为一个子句(clause)。

1.4 代码组由不同的缩进分隔

  代码的层次关系通过同样深度的空格或制表符缩进来体现,同一代码组的代码行必须严格左对齐。

  没有缩进的代码块是最高层次的,称为脚本的main部分。

1.5 同一行书写多个语句

  多个语句写在同一行的话,之间用分号(;)隔开,这些语句同属一个代码块(子句),中间不能开始新的代码块。

1.6 模块

  每个Python脚本文件都可以当成一个模块,模块以磁盘文件形式存在。如果一个模块太大,功能太多,应考虑拆分到多个模块中。

2 变量赋值

  Python通过等号=、增量赋值运算符+=(-=、*=等)来赋值。

  Python中,对象是通过引用传递的。在赋值时,不管这个对象是新创建的,还是一个已经存在的,都是将该对象的引用(并不是值)赋值给变量。(要有对象的概念,名字只是一个符号/指针,指向被赋值的对象)

  Python中的链式赋值(多重赋值),只是对象的同一个引用被赋给了多个变量。Python的赋值语句不会返回值(与C不同)。

>>> x = y = z = 1
>>> x
1
>>> y
1
>>> z
1
>>> x = ( y = 13 )
File "<stdin>", line 1
x = ( y = 13 )
^
SyntaxError: invalid syntax

  增量赋值,同样适合与列表/字符串;++n、--n被解析为+(+n)、-(-n),n++、n--是语法错误。

+=    -=   *=   /=   %=   **=  #Python支持的增量赋值符
<<= >>= &= ^= |=
>>> aList = [123, 'xyz']
>>> aList += [45.6e7]  #列表加
>>> aList
[123, 'xyz', 456000000.0] >>> n=3
>>> --n  #与C语言不同
3
>>> n
3
>>> n--  #语法错误
File "<stdin>", line 1
n--
^
SyntaxError: invalid syntax

  多元赋值,即同时给多个变量赋值:

>>> x, y, z = 1, 2, 'a string'  #等号两边实质是元组,建议总是加上括号,即  (x, y, z) = (1, 2, 'string')
>>> x
1
>>> y
2
>>> z
'a string'
>>> x, y = 1, 2
>>> x
1
>>> y
2
>>> x, y = y, x  #不需要中间变量,即可交换两个变量值
>>> x
2
>>> y
1

3 标识符

  合法标识符:同C语言,字母或下划线_开头,后面可以是字母、数字或下划线;大小写敏感。

  关键字:关键字列表kwlist和iskeyword()函数都放入了keyword模块以便查阅。

and

as assert break
class continue def del
elif else except exec
finally for from global
if import in is
lambda not or pass
print raise return try
while with yield None
>>> import keyword
>>> keyword.iskeyword('and')
True

  内建:除了关键字之外,Python还有可以在任何一级代码使用的“内建”的名字集合,这些名字可以由解释器设置或使用,应该把它当作“系统保留字”,不做他用。Python不支持重载标识符,任何时刻都只有一个名字绑定。内建built-in是__builtins__模块的成员,在程序开始或在交互解释器中给出>>>提示之前,由解释器自动导入的。把它们看成适用在任何一级Python代码的全局变量。

  类变量的专用下划线标识符:

_xxx      #不用'from module import *'导入,外部可以访问,但是应视其为 私有变量
__xxx__ #系统定义名字,特殊变量,可以直接访问,自己不要使用这种变量名
__xxx #类中的私有变量名,外部无法访问(实质上,一般的编译器,都将其改名为 _所属类名__xxx)

4 基本风格指南

  添加注释,写字串文档,采用合适缩进,尽量使用简短的变量名。  

import this  #可以看到Python之禅

4.1 模块结构和布局

  编写脚本文件pytest.py,并执行:

#/usr/bin/env python        #1.起始行(Unix) / 模块注释
# -*- coding: utf-8 -*- #如果代码包含中文,需要添加该行(由于出现在该注释之前,上一行的中文注释会被报错) "this is a test module" #2.模块文档,可通过 模块名.__doc__ 直接访问 import sys #3.导入所需的模块
import os debug = True #4.全局变量。尽量少使用全局变量,有利于代码维护,提高性能,节省内存 class FooClass(object): #5.类定义,模块被导入时类就会被定义
"Foo class" #类文档,可通过 模块名.类名.__doc__ 来访问
pass def test(): #6.函数定义,模块被导入时类就会被定义,可通过 模块名.函数名() 来访问
"test function" #函数文档,可通过 模块名.函数名.__doc__ 来访问
foo = FooClass() #类对象
if debug:
print 'ran test()' if __name__ == '__main__': #7.主程序部分,通常只包含函数调用,无论是被导入还是作为脚本执行,都会执行这部分代码
test() #如果模块直接执行,则__name__值为'__main__',该句执行;如果被导入,则__name__值为模块名
$ python pytest.py    #作为脚本直接执行
ran test() >>> import pytest #交互解释器中,导入模块,主程序部分的if条件不成立。模块名即去掉后缀的文件名
>>> pytest.__doc__  #模块文档
'this is a test module'
>>> pytest.FooClass.__doc__ #模块内的类文档
'Foo class'
>>> pytest.test() #执行模块内函数
ran test()

  没有缩进的代码,在模块被导入时就会被执行(所以导入模块时,类、函数就会被定义),所以安全的写代码方式:除了真正要执行的代码,把其他功能代码都写在函数当中。

  绝大部分的模块,其创建的目的就是被导入,所以应该尽量只包括类、函数的定义。很多项目都只有一个主程序部分,由它导入模块、调用函数。

4.2 在主程序中书写测试代码

  测试代码应该在模块直接执行时被执行,模块被导入时不执行。(即用到上面例子的最后if语句)

  测试代码应随着测试条件、结果变更时及时更新,且每次代码更新后都应执行测试代码,以确认没有新问题。

5 内存管理

5.1 变量定义

  变量无需声明,第一次被赋值时自动声明。

>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> x=4
>>> x
4

5.2 动态类型

  变量的类型和占用的内存,都是运行时确定的。赋值时,解释器根据语法和右操作数来决定新对象类型。对象创建后,将其引用赋给左边变量。

5.3 内存分配

  Python解释器负责内存管理,程序员无需关心。

5.4 引用计数

  Python内部记录着使用中的对象各有多少引用,对象的引用数目简称引用计数。当对象的引用计数为0时,它就被垃圾回收。

  增加引用计数:

x = 3.14    #对象被创建
y = x   #对象的别名被创建,即对象被赋值给一个新变量
foobar(x) #对象作为参数传递给函数(新的本地引用)
myList = [123, x, 'xyz'] #对象成为容器对象的一个元素

  减少引用计数:

一个本地引用离开了其作用范围,比如上面的foobar()函数结束时。
del y   #对象的别名被显式的销毁
x = 123 #对象的一个别名被赋值给其它的对象
myList.remove(x) #对象被从一个窗口对象中移除
del myList  #窗口对象本身 离开作用范围 或 被销毁

  del语句:

del  obj1[, obj2[...]]     #可以一次删除多个对象的引用

  上面的 del y,会将y从现在的名字空间中删除,且y指向的对象引用计数减1。再执行del x后,该对象引用计数为0,对象从此“无法访问”。追踪或调试程序会增加对象的一个额外引用。

5.5 垃圾收集

  垃圾收集器是一段独立代码,用来寻找 引用计数为0的对象,也检查那些 引用计数不为0但应该被销毁的对象,然后释放其内存。

  当两个对象相互引用时,引用计数可能不会为0,因此垃圾收集器也包含循环垃圾收集器,来清理未引用的循环。

6 第一个Python程序

  介绍两个处理文本文件的脚本,分别实现写入/读取文件内容。

  makeTextFile.py,创建文件,输入每行文本:

#!/usr/bin/env python

'makeTextFile.py -- create text file'

import os
ls = os.linesep #换行符,Unix为'\n',Windows为'\r\n',用os.linesep则不需关心平台。起个别名,减少名字查询,代码跑得快,名字也短 while True:
fname = raw_input('Enter filename: ')
if os.path.exists(fname): #判断文件是否已存在,存在则返回True
print "ERROR: '%s' already exists" % fname
else:
break all = []
print "\nEnter lines ('.' by itself to quit).\n" while True:
entry = raw_input('> ')
if entry == '.': #输入'.'时结束输入
break
else:
all.append(entry) #将输入内容添加到列表中 fobj = open(fname, 'w')
fobj.writelines(['%s%s' % (x, ls) for x in all]) #列表解析。writelines接收包含行结束符的结果列表,并写入文件
fobj.close()
print 'DONE!'

  readTextFile.py,读取并显示文本内容:

#!/usr/bin/env Python

'readTextFile.py -- read and display text file'

fname = raw_input('Enter filename: ')
print try: #捕获异常语句,适用于没有合适函数处理异常的情况。这里没有使用上面的os.path.exsits()函数,因为打开文件错误可能不仅仅是文件名错误导致
fobj = open(fname, 'r')
except IOError, e: #如果打开文件错误,则捕获异常,并输出异常提示信息,然后跳过else
print "*** file open error:", e
else: #如果成功打开文件,则执行该子句
for eachLine in fobj:
print eachLine,  #创建文件时,我们人为加入了换行符,所以这里打印的时候要抑制print生成的换行符
fobj.close()

7 相关模块和开发工具

  工具:Python代码风格指南(PEP8),Python快速参考和Python常见问答。

  模块:

  • 调试模块pdb:允许设置(条件)断点,代码逐行执行,检查堆栈。还支持事后调试。
  • 日志模块logging:定义了一些函数和类帮程序实现灵活的日志系统。有五级日志级别:紧急,错误,警告,信息,调试。
  • 性能测试模块:profile,hotshot,cProfile。

练习题

3–11 字符串格式化 不再抑制readTextFile.py中print语句生成的 NEWLINE 字符,修改你的代码,在显示一行之前删除每行末尾的空白。这样,你就可以移除print语句末尾的逗号了。

提示:使用字符串对象的strip()方法

 #!/usr/bin/env Python

 'readTextFile.py -- read and display text file'

 fname = raw_input('Enter filename: ')
print try:
fobj = open(fname, 'r')
except IOError, e:
print "*** file open error:", e
else:
for eachLine in fobj:
print eachLine.strip() #将逗号改为 .strip() ,此时读入的字串后面的换行符作为空白被舍弃,但是仍然输出print的换行符
fobj.close()

3-11

Python核心编程--学习笔记--3--Python基础的更多相关文章

  1. Python核心编程--学习笔记--4--Python对象

    现在开始学习Python语言的核心部分.首先了解什么是Python对象,然后讨论最常用的内建类型,接下来讨论标准类型运算符和内建函数,之后给出对标准类型的不同分类方式,最后提一提Python目前还不支 ...

  2. Python核心编程--学习笔记--1--Python简介

    本章介绍了Python的背景知识,包括什么是Python.Python的起源以及Python的一些关键特性. 1 什么是Python Python是一门优雅而健壮的编程语言,它继承了传统编译语言的强大 ...

  3. Python核心编程--学习笔记--6--序列(上)字符串

    本章研究Python中的序列:字符串.列表和元组.因为这些类型其实都是由一些成员共同组成的一个序列整体,所以我们把它们统称为序列.序列的存储结构可以表示为: 1 序列 序列类型有着相同的访问模式:按下 ...

  4. Python核心编程--学习笔记--9--文件和输入输出

    本章将深入介绍Python的文件处理和相关输入输出能力,包括:文件对象(以及它的内建函数.内建方法和属性),标准文件,文件系统的访问方法,文件执行,最后简要涉及持久存储和标准库中与文件有关的模块. 1 ...

  5. Python核心编程--学习笔记--8--条件与循环

    本章讲述if.while.for以及与他们搭配的else.elif.break.continue.pass等语句. 1 if语句 语法:三部分——关键字if.条件表达式.代码块.(记住冒号) if c ...

  6. Python核心编程--学习笔记--7--字典和集合

    本章介绍Python语言中的映射类型(字典)和集合类型,包括操作符.工厂函数.内建函数与方法. 1 字典 字典是Python中唯一的映射类型——键key直接映射到值value.字典是容器类型,其对象是 ...

  7. Python核心编程--学习笔记--6--序列(下)列表、元组

    11 列表 类似于C语言的数组,但是列表可以包含不同类型的任意对象.列表是可变类型. 创建列表——手动赋值.工厂函数: >>> aList = [12, 'abc'] >> ...

  8. Python核心编程--学习笔记--5--数字

    本章的主题是Python中的数字,这里详细介绍每一种数字类型,它们适用的各种运算符,以及用于处理数字的内建函数.在本章的末尾简单介绍了几个标准库中用于处理数字的模块. 1 数字类型 数字:标量贮存,可 ...

  9. Python核心编程--学习笔记--2--Python起步(下)

    16 文件和内建函数open(),file() 打开文件: fobj = open(filename, 'r') for eachLine in fobj: print eachLine, #由于每行 ...

随机推荐

  1. 02-自定义CALayer

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  2. C# ToolStripProgressBar

    ToolStripProgressBar 将所有 ToolStrip控件的移动和渲染功能和其典型的进程跟踪功能结合在一起.ToolStripProgressBar通常放在StatusStrip中,偶尔 ...

  3. android 如何设置背景的透明度

    半透明<Button android:background="#e0000000" ... />透明<Button android:background=&quo ...

  4. Effective Modern C++翻译(7)-条款6:当auto推导出意外的类型时,使用显式的类型初始化语义

    条款6:当auto推导出意外的类型时,使用显式的类型初始化语义 条款5解释了使用auto来声明变量比使用精确的类型声明多了了很多的技术优势,但有的时候,当你想要zag的时候,auto可能会推导出了zi ...

  5. win8或win8.1修改注册表失败的原因

    win8 and win8.1 modify the registry need compiled to be different versions according to the os bits.

  6. 【测试】在hr用户下自行创建T1和T2表写一条SQL语句,(NL连接)

    SQL> select t1.* from t1,t2 where t1.object_id=t2.object_id; rows selected. Execution Plan ------ ...

  7. USACO Section 3.3 游戏 A Game

    OJ:http://www.luogu.org/problem/show?pid=2734 #include<iostream> #include<cstring> using ...

  8. 图说苹果工作站-MAC PRO

    图说苹果工作站-MACPRO MacPro是苹果电脑公司(Apple)推出的高阶桌上型电脑(上一代产品叫做PowerMacG5),搭载英特尔(Intel)"Xeon"微处理器以及& ...

  9. C++断言与静态断言

    断言是很早之前就有的东西了,只需要引入cassert头文件即可使用.往往assert被用于检查不可能发生的行为,来确保开发者在调试阶段尽早发现“不可能”事件真的发生了,如果真的发生了,那么就表示代码的 ...

  10. android Tab =viewpager+fragmnet

    1.定义几个fragment 的subclass 如fragmentone,fragmenttwo; public class fragmentthree extends Fragment { pri ...