本章介绍基本的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 |
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基础的更多相关文章
-
Python核心编程--学习笔记--4--Python对象
现在开始学习Python语言的核心部分.首先了解什么是Python对象,然后讨论最常用的内建类型,接下来讨论标准类型运算符和内建函数,之后给出对标准类型的不同分类方式,最后提一提Python目前还不支 ...
-
Python核心编程--学习笔记--1--Python简介
本章介绍了Python的背景知识,包括什么是Python.Python的起源以及Python的一些关键特性. 1 什么是Python Python是一门优雅而健壮的编程语言,它继承了传统编译语言的强大 ...
-
Python核心编程--学习笔记--6--序列(上)字符串
本章研究Python中的序列:字符串.列表和元组.因为这些类型其实都是由一些成员共同组成的一个序列整体,所以我们把它们统称为序列.序列的存储结构可以表示为: 1 序列 序列类型有着相同的访问模式:按下 ...
-
Python核心编程--学习笔记--9--文件和输入输出
本章将深入介绍Python的文件处理和相关输入输出能力,包括:文件对象(以及它的内建函数.内建方法和属性),标准文件,文件系统的访问方法,文件执行,最后简要涉及持久存储和标准库中与文件有关的模块. 1 ...
-
Python核心编程--学习笔记--8--条件与循环
本章讲述if.while.for以及与他们搭配的else.elif.break.continue.pass等语句. 1 if语句 语法:三部分——关键字if.条件表达式.代码块.(记住冒号) if c ...
-
Python核心编程--学习笔记--7--字典和集合
本章介绍Python语言中的映射类型(字典)和集合类型,包括操作符.工厂函数.内建函数与方法. 1 字典 字典是Python中唯一的映射类型——键key直接映射到值value.字典是容器类型,其对象是 ...
-
Python核心编程--学习笔记--6--序列(下)列表、元组
11 列表 类似于C语言的数组,但是列表可以包含不同类型的任意对象.列表是可变类型. 创建列表——手动赋值.工厂函数: >>> aList = [12, 'abc'] >> ...
-
Python核心编程--学习笔记--5--数字
本章的主题是Python中的数字,这里详细介绍每一种数字类型,它们适用的各种运算符,以及用于处理数字的内建函数.在本章的末尾简单介绍了几个标准库中用于处理数字的模块. 1 数字类型 数字:标量贮存,可 ...
-
Python核心编程--学习笔记--2--Python起步(下)
16 文件和内建函数open(),file() 打开文件: fobj = open(filename, 'r') for eachLine in fobj: print eachLine, #由于每行 ...
随机推荐
-
我叫Twenty,我是要成为博客王的博客框架
标题套用了路飞的格式,其实我想说的是大多数都不相信你的梦想,直到你快走到了. 不废话了,介绍一下twenty: 这是基于CMS框架 zerojs打造一个博客.zerojs 的架构介绍在这里http:/ ...
-
Coursera上一个不错的Java课
地址:https://www.coursera.org/learn/java-chengxu-sheji/home/welcome 复习天昏地暗,看点视频调剂一下.发现这个讲的还是很不错的.北大毕竟比 ...
-
make things simple
以前看过一篇文章,具体内容不记得了,只记得它的结论了:懒是人类进步的源动力.当时觉得结论有点新颖,文中列举了大量的实例证明这个结论,其中重点强调了计算机学科.我本身从事算是计算机相关的工作,对文中的部 ...
-
使用 JDBC 和 JavaTemplate 查询SQL语句返回 List<;Map<;String,Object>;>;
使用JDBC执行sql语句返回List 类型: public class JdbcUtil { private static Log log = LogFactory.getLog(JdbcUtil. ...
-
Android MVC模式
Android MVC模式 下面是我对Android MVC模式的理解 Model 模型层 包括实体模型层,存放程序中调用的实体. 业务模型层,存放程序中调用的业务逻辑. View 显示层 An ...
-
脱离rails 使用Active Record
目录结构 database.yml development: adapter: sqlite3 database: db/test.db pool: 5 timeout: 5000 001_schem ...
-
C# 运用params修饰符来实现变长参数传递
一般来说,参数个数都是固定的,定义为集群类型的参数可以实现可变数目参数的目的,但是.NET提供了更灵活的机制来实现可变数目参数,这就是使用params修饰符.可变数目参数的好处就是在某些情况下可以方便 ...
-
Hyper-V中安装CentOS分辨率修改
Hyper-V还是极好用的,不过对linux的支持优点问题, 比如默认情况,linux分辨率被锁定了,这里有一个比较简单的方法修改,针对CentOS grubby --update-kernel=AL ...
-
having的用法以及与where区别介绍
having子句可以让我们筛选成组后的各种数据,having子句在查询过程中慢于聚合语句,接下来通过实例介绍下,感兴趣的你可以参考下,希望可以帮助到你 having的用法 having子句可以让我们筛 ...
-
23种设计模式+J2EE设计模式学习笔记-初识设计模式
设计模式简介: 设计模式是一套被反复使用的.多数人知晓的.经过分类编目的.代码设计经验的总结.(个人理解:设计模式是不关乎业务,逻辑实现,针对普遍问题的一种解决方案). 设计模式的类型: 传统23种设 ...