Python Learning
这是自己之前整理的学习Python的资料,分享出来,希望能给别人一点帮助。
Learning Plan
- Python是什么?- 对Python有基本的认识
- 版本区别
- 下载
- 安装
- IDE
- 文件构造
- Python语言 - 基础的语言知识
- 变量
- 数据类型
- 列表/元组/字典/集合
- 条件语句
- 循环语句
- 函数
- 模块
- 面向对象
- 异常处理
- Python命令行运行时带参数
- Reference
Python是什么?- 对Python有基本的认识
Python为我们提供了非常完善的基础代码库,覆盖了网络、文件、GUI、数据库、文本等大量内容,被形象地称作“内置电池(batteries included)”。用Python开发,许多功能不必从零编写,直接使用现成的即可。
除了内置的库外,Python还有大量的第三方库,也就是别人开发的,供你直接使用的东西。当然,如果你开发的代码通过很好的封装,也可以作为第三方库给别人使用。
Python的定位是“优雅”、“明确”、“简单”,所以Python程序看上去总是简单易懂,初学者学Python,不但入门容易,而且将来深入下去,可以编写那些非常非常复杂的程序。 总的来说,Python的哲学就是简单优雅,尽量写容易看明白的代码,尽量写少的代码。
任何编程语言都有缺点,Python也不例外。第一个缺点就是运行速度慢, 和C程序相比非常慢,因为Python是解释型语言,代码在执行时会一行一行地翻译成CPU能理解的机器码,这个翻译过程非常耗时,所以很慢。而C程序是 运行前直接编译成CPU能执行的机器码,所以非常快。但是大量的应用程序不需要这么快的运行速度,因为用户根本感觉不出来。第二个缺点就是代码不能加密。 如果要发布Python程序,实际上就是发布源代码,这一点跟C语言不同,C语言不用发布源代码,只需要把编译后的机器码(也就是Windows上常见 的.exe文件)发布出去。要从机器码反推出C代码是不可能的,所以,凡是编译型的语言,都没有这个问题,而解 释型的语言,则必须把源码发布出去。Python还有其他若干小缺点,不一一列举。
版本区别
目前,Python有两个版本,一个是2.x版,一个是3.x版,这两个版本是不兼容的。当初为了修复2.x版本中的一些问题,并且不带入过多的累赘,3.X版本在设计的时候没有考虑向下相容。两个版本具体区别可以参考后面的参考链接。
下载
https://www.python.org/downloads/
安装
Python可应用于多平台包括 Windows,Linux 和 Mac OS X。
以下为在 Window 平台上安装 Python 2.7的简单步骤:
- 打开WEB浏览器访问http://www.python.org/download/
- 在下载列表中选择Window平台安装包,包格式为:python-XYZ.msi 文件 , XYZ 为你要安装的版本号。
- 下载后,双击下载包,进入Python安装向导,安装非常简单,要注意选上"Add python.exe to Path".
- 你只需要使用默认的设置一直点击"下一步"直到安装完成即可。
以下为安装Python3的简单步骤:
- 下载后,双击下载包,进入Python安装向导,注意选上"Add Python 3.x to Path".
- 选择自定义安装
- 修改安装路径为C:\Python35
- 使用默认的设置一直点击"下一步"直到安装完成即可。
可以先后安装2.7和3两个版本,并作以下设置让其共存。
- 确保环境变量PATH中有这些值,C:\Python35\Scripts\;C:\Python35\;C:\Python27\Scripts\;C:\Python27\;
- 重命名C:\Python35\python.exe为C:\Python35\python3.exe
之后在命令行窗口输入python即调用python2.7,输入python3即调用python3.5
IDE
在Python的交互式命令行写程序,好处是一下就能得到结果,坏处是没法保存,下次还想运行的时候,还得再敲一遍。所以,实际开发脚本的时候,需要使用一个文本编辑器或IDE来写代码,写完了,保存为一个后缀为.
py的文件,这样程序就可以反复运行了。推荐两款文本编辑器:一个是Sublime Text,免费使用,但是不付费会弹出提示框。一个是Notepad++,免费使用,有中文界面。但是如果要比较方便地设置断点、单步执行,就需要一个支持调试功能的IDE。目前比较好的Python IDE有PyCharm
请注意,绝对不能用Word和Windows自带的记事本。Word保存的不是纯文本文件,而记事本会自作聪明地在文件开始的地方加上几个特殊字符(UTF-8 BOM),结果会导致程序运行出现莫名其妙的错误。
Python的交互模式和直接运行.
py文件的区别:
直接输入Python进入交互模式,相当于启动了Python解释器,但是等待你一行一行地输入源代码,每输入一行就执行一行。
直接运行.py
文件相当于启动了Python解释器,然后一次性把.
py文件的源代码给执行了,没有机会以交互的方式输入源代码的。
用Python开发程序,完全可以一边在文本编辑器里写代码,一边开一个交互式命令窗口,在写代码的过程中,把部分代码粘到命令行去验证,事半功倍!
文件构造
示例:
#!/usr/bin/python # -*- coding: UTF-8 -*- # 文件名:test.py # 第一个注释 print ("Hello, Python!") # 第二个注释 # 代码块语句必须包含相同的缩进空白数量 if True: print ("True") else: print ("False") # 使用斜杠( \)将一行的语句分为多行显示 total = item_one + \ item_two + \ item_three # 包含 [], {} 或 () 括号就不需要使用多行连接符 days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] # 引号( ' )、双引号( " )、三引号( ''' 或 """ ) 来表示字符串 word = 'word' sentence = "这是一个句子。" paragraph = """这是一个段落。 包含了多个语句""" # 在同一行中使用多条语句 import sys; x = 'runoob'; sys.stdout.write(x + '\n') # 不换行输出 x="a" y="b" print x, print y, # 输出: a b # if、while、def和class这样的复合语句, 以冒号( : )结束 if expression : suite elif expression : suite else : suite
- python 中单行注释采用 # 开头。第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码, 否则,你在源代码中写的中文输出可能会有乱码。申明了UTF-8编码并不意味着你的
.py
文件就是UTF-8编码的,必须并且要确保文本编辑器正在使用UTF-8 without BOM编码 - Python的代码块不使用大括号({})来控制类,函数以及其他逻辑判断。python使用缩进来写模块。缩进的空白数量是可变的,但是所有代码块语句必须包含相同的缩进空白数量。
- Python语句中一般以新行作为语句的结束符。但是我们可以使用斜杠( \)将一行的语句分为多行显示,语句中包含 [], {} 或 () 括号就不需要使用多行连接符。
- Python还支持在一行最后以分号作为结尾,但建议最好不要写分号,以使脚本更规范整洁。
- Python 可以使用引号( ' )、双引号( " )、三引号( ''' 或 """ ) 来表示字符串,引号的开始与结束必须的相同类型的。常用于文档字符串,在文件的特定地点,被当做注释。
- Python可以在同一行中使用多条语句,语句之间使用分号(;)分割
- print 默认输出是换行的,如果要实现不换行需要在变量末尾加上逗号
- 空行与代码缩进不同,空行并不是Python语法的一部分。书写时不插入空行,Python解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码,便于日后代码的维护或重构。
Python语言 - 基础的语言知识
变量
变量在程序中就是用一个变量名表示了,变量名必须是大小写英文、数字和_
的组合,且不能用数字开头。
变量值可以指定不同的数据类型。
变量是区分大小写的。
以下划线开头的标识符是有特殊意义的。以单下划线开头 _foo 的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用 from xxx import * 而导入
以双下划线开头的 __foo 代表类的私有成员,以双下划线开头和结尾的 __foo__ 代表 Python 里特殊方法专用的标识,如 __init__() 代表类的构造函数。
Python中的变量不需要声明,变量的赋值操作既是变量声明和定义的过程。
每个变量在内存中创建,都包括变量的标识,名称和数据这些信息。
每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。
等号(=)用来给变量赋值。等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的值。
变量的命名规则
- 命名规则可以被视为一种 惯例,并无绝对与强制
- 目的是为了 增加代码的识别和可读性
- 在定义变量时,为了保证代码格式,= 的左右应该各保留一个空格
- 在Python中,如果 变量名 需要由 二个 或 多个单词 组成时,可以按照以下方式命名
- 每个单词都使用小写字母
- 单词与单词之间使用 _下划线 连接
- 例如:first_name、ast_name、qq_number、qq_password
- 当 变量名 是由二个或多个单词组成时,还可以利用驼峰命名法来命名
- 小驼峰式命名法
第一个单词以小写字母开始,后续单词的首字母大写。例如:firstName、lastName - 大驼峰式命名法
每一个单词的首字母都采用大写字母。例如:FirstName、LastName、CamelCase
数据类型
Python提供的基本数据类型主要有:整型、浮点型、字符串、布尔值、列表、元组、集合、字典等等
整型(int)
数学上的写法一模一样,例如:1
,100
,-8080
,0
,等等。
浮点型(float)
浮点数可以用数学写法,如1.23
,3.14
,-9.01
,等等。但是对于很大或很小的浮点数,就必须用科学计数法表示,把10用e替代,1.23x109就是1.23e9
,或者12.3e8
,0.000012可以写成1.2e-5
,等等。
整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的,而浮点数运算则可能会有四舍五入的误差。
Python支持的最大浮点数:
import sys sys.float_info
字符串(str)
字符串是以单引号'
或双引号"
括起来的任意文本,比如'abc'
,"xyz"
等等。请注意,''
或""
本身只是一种表示方式,不是字符串的一部分,因此,字符串'abc'
只有a
,b
,c
这3个字符。如果'
本身也是一个字符,那就可以用""
括起来,比如"I'm OK"
包含的字符是I
,'
,m
,空格,O
,K
这6个字符
如果字符串内部既包含单引号'
又包含双引号"
, 可以用转义字符\
来标识。转义字符\
可以转义很多字符,比如\n
表示换行,\t
表示制表符,\\表示字符\
本身也要转义。print '\\\t\\'
如果字符串里面有很多字符都需要转义,就需要加很多\
,为了简化,Python还允许用r''
表示''
内部的字符串默认不转义。print r'\\\t\\'
如果字符串内部有很多换行,用\n
写在一行里不好阅读,为了简化,Python允许用三引号'''...'''或"""..."""
的格式表示多行内容,三个单引号或三个双引号都可以。三个引号能包含多行字符串,同时常常出现在函数的声明的下一行,来注释函数的功能,与众不同的地方在于,这个注释作为函数的一个默认属性,可以通过 函数名.__doc__ 来访问
print '''line1 line2 line3'''
字符串编码问题请详见后面的参考链接。
格式化
在Python中,采用%
实现格式化,举例如下:
print 'Hello, %s' % 'world' print 'Hi, %s, you have $%d.' % ('Michael', 1000000) print 'num=%.2f' %3.1415926 print 'num=%10d' %12345
在字符串内部,%s
表示用字符串替换,%d
表示用整数替换,%f表示用浮点数替换,%x表示用十六进制整数替换。
有几个%
占位符,后面就跟几个变量或者值,顺序要对应好。如果只有一个,括号可以省略。
不太确定应该用什么,%s
永远起作用,它会把任何数据类型转换为字符串。
字符串里面的%
是一个普通字符怎么办?这个时候就需要转义,用%%
来表示一个%
:
print 'growth rate: %d%%' %7
布尔值(bool)
布尔值和布尔代数的表示完全一致,一个布尔值只有True
、False
两种值,要么是True
,要么是False
,在Python中,可以直接用True
、False
表示布尔值,也可以通过布尔运算计算出来。布尔值可以用and
、or
和not
运算。
空值
空值是Python里一个特殊的值,用None
表示。None
不能理解为0
,因为0
是有意义的,而None
是一个特殊的空值。
Python中不同的类型的数据,初始化为空的值,比如null之类的,对应的写法是:
数值 | digital_value = 0 |
字符串 | str_value = "" 或 str_value = ” |
列表 | list_value = [] |
元祖 | tuple_value = () |
字典 | dict_value = {} |
列表/元组/字典/集合
列表:(list)
list1 = ['physics', 'chemistry', 1997, 2000]; list2 = [1, 2, 3, 4, 5 ]; list3 = ["a", "b", "c", "d"]; print "list1[0]: ", list1[0] print "list2[1:5]: ", list2[1:5] list2[2] = 2001; del list3[2];
列表的应用场景
尽管python 中的列表可以存储不同类型的数据,但是在开发中,更多的应用场景是:
1.列表存储相同类型的数据
2.通过迭代遍历,在循环体内部,针对列表中的每一项元素,执行相同的操作。
元组(tuple)
tup1 = ('physics', 'chemistry', 1997, 2000); tup2 = (1, 2, 3, 4, 5 ); tup3 = ("a", "b", "c", "d");
Python的元组与列表类似,不同之处在于元组的元素不能修改
元组的应用场景
尽管可以使用for in 遍历元祖,但是在开发中,更多的应用场景是:
1. 函数的参数和返回值,一个函数可以接受任意多个参数
2. 依次返回多个数据格式化字符串,格式化字符串后面的()本质上就是一个元祖;让列表不可以修改,以保护数据安全
字典
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}; print "dict['Name']: ", dict['Name']; print "dict['Age']: ", dict['Age'];
不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住
键必须不可变,所以可以用数字,字符串或元组充当,但是用列表就不行
键区分字母大小写
集合
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
s = set([1, 1, 2, 2, 3, 3])
s = set([1, 2, 3])
传入的参数[1, 2, 3]
是一个list,而显示的set([1, 2, 3])
只是告诉你这个set内部有1,2,3这3个元素,显示的[]不表示这是一个list。
集合用法:
list1=[1,2,2,2,3,4,4,5] list2=[2,3,5,98,23] list(set(list1)&set(list2)) list(set(list1)|set(list2)) list(set(list1)-set(list2)) list(set(list2)-set(list1))
条件语句
Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块
if 判断条件: 执行语句…… else: 执行语句……
或者
if 判断条件1: 执行语句1…… elif 判断条件2: 执行语句2…… elif 判断条件3: 执行语句3…… else: 执行语句4……
还有一种简单语句。只要判断条件
是非零数值、非空字符串、非空list等,就判断为True
,否则为False
var = 100 if ( var == 100 ) : print "变量 var 的值为100"
循环语句
循环有两种,一种是for...in循环,依次把list或tuple中的每个元素迭代出来
sum = 0 for x in range(101): #range范围从0到100 sum = sum + x print sum
第二种循环是while循环,只要条件满足,就不断循环,条件不满足时退出循环
sum = 0 n = 99 while n > 0: sum = sum + n n = n - 2 print sum
for … else 表示这样的意思和else的循环语句没有区别,else 中的语句会在循环正常执行完(即 for 不是通过 break 跳出而中断的)的情况下执行,while … else 也是一样
break语句
break语句用来终止循环语句,即循环条件没有False条件或者序列还没被完全递归完,也会停止执行循环语句。break语句用在while和for循环中。
continue语句
continue 语句用来告诉Python跳过当前循环的剩余语句,然后继续进行下一轮循环。continue语句用在while和for循环中。
for letter in 'Python': # First Example if letter == 'h': continue print 'Current Letter :', letter var = 10 # Second Example while var > 0: var = var -1 if var == 5: continue print 'Current variable value :', var print "Good bye!"
pass语句
Python pass是空语句,是为了保持程序结构的完整性。pass 不做任何事情,一般用做占位语句。
函数
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
- 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。参数可以是必选参数、默认参数、可变参数和关键字参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
- 执行到return语句时,会退出函数,return之后的语句不再执行。。。
- 函数可以同时返回多个值,但其实就是一个tuple。
-
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
- 定义函数时,必选参数在前,默认参数在后,变化大的参数放前面,变化小的参数放后面,可以作为默认参数。默认参数值一定要用不可变的。
- 调用函数时,默认参数的值如果没有传入,则被认为是默认值。
- Python的内建函数
def printinfo( name, score, age = 15, location="Wuxi"): print "Name: ", name; print "score:", score print "Age: ", age; print "Location: ", location; return; printinfo( age=16, name="miki", score=90 ); #使用关键字参数允许函数调用时参数的顺序与声明时不一致 printinfo( score=99, location="Suzhou", name="xiaowang" ); printinfo("xiaoxin",85) #省略关键字参数名
可变参数*args
,args接收的是一个元祖tuple
def calc(*numbers): sum = 0 for n in numbers: sum = sum + n * n print(sum) calc(90,99,85) nums = [1, 2, 3] calc(nums[0], nums[1], nums[2]) calc(*nums)
关键字参数**kw
, kw接收的是一个字典dict
def person(name, age, **kw): print 'name:', name, 'age:', age, 'other:', kw person('Adam', 45, gender='M', job='Engineer') kw = {'city': 'Beijing', 'job': 'Engineer'} person('Jack', 24, **kw)
定义函数,可以用必选参数、默认参数、可变参数和关键字参数,这4种参数都可以一起使用,或者只用其中某些,参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数
模块
模块就是一个保存了Python代码的文件。模块能定义函数,类和变量。模块里也能包含可执行的代码
import datetime import __builtin__ from xlrd import open_workbook,cellname import xlrd
安装第三方模块
Python有2种安装第三方模块的方法。esay_install和pip
一般第三方模块可以从Python官网下载。下载解压后,进入安装包目录,运行以下命令就可完成安装:
python setup.py install
或
pip install <module name>
自定义模块
自定义的模块,如一个hello.py文件需要导入时,需放置在以下特定的位置,通过import hello语句就可以使用模块中定义的函数。因为当导入一个模块,Python解析器会对模块位置按顺序搜索:
- 当前目录
- 如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录。
- 如果都找不到,Python会察看默认路径。
模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。
包
包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的Python的应用环境。
假设Phone目录下的pots.py文件,保存了函数Posts(), 另外有两个保存了不同函数的文件:
- Phone/Isdn.py 含有函数Isdn()
- Phone/G3.py 含有函数G3()
在Phone目录下创建file __init__.py:
- Phone/__init__.py
from Pots import Pots from Isdn import Isdn from G3 import G3
之后导入Phone包的时候,Pots, Isdn, G3都会被导入。使用方法如下:
import Phone Phone.Pots() Phone.Isdn() Phone.G3()
面向对象
使用class语句来创建一个新类,class之后为类的名称,紧接着是(object)
,并以冒号结尾
类(Class)是抽象的模板,而实例(Instance)是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同
class Employee(object): empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" %Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary emp1 = Employee("Zara", 2000) emp2 = Employee("Manni", 5000) emp1.age = 8 emp2.age = 9 emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" %Employee.empCount
empCount变量是一个类变量,它的值将在这个类的所有实例之间共享。可以在内部类或外部类使用Employee.empCount访问。
方法就是与实例绑定的函数,和普通函数不同,类方法必须包含参数self,且为第一个参数。方法可以直接访问实例的数据;使用点(.)来访问对象的方法。
第一种方法__init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法。要创建一个类的实例时,可以使用类的名称,并通过__init__方法接受参数。__init__
方法的第一个参数永远是self
,表示创建的实例本身,因此,在__init__
方法内部,就可以把各种属性绑定到self
,因为self
就指向创建的实例本身,不需要传递该参数。
有了__init__
方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__
方法匹配的参数。
继承
定义一个class的时候,可以从某个现有的class继承,新的class称为子类,派生类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class),子类获得了父类的全部功能。当子类和父类都存在相同的的方法时,子类的方法
覆盖了父类的方法,这是继承关系中的另一特点:多态
。
class
后面紧接着是类名,紧接着是(object)
,表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就使用object
类,这是所有类最终都会继承的类。所以对于上面的class Employee:类,这样写class Employee(object):是一样的。
class Parent(object): parentAttr = 100 def __init__(self): print "invoke parent class" def parentMethod(self): print 'invoke parent method' def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print "parent attribute :", Parent.parentAttr class Child(Parent): def __init__(self): print "invoke child class" def childMethod(self): print 'invoke child method' c = Child() c.childMethod() c.parentMethod() c.setAttr(200) c.getAttr()
如果在继承元组中列了一个以上的类,那么它就被称作"多重继承"
class A: ..... class B: ..... class C(A, B): .....
在python中继承中的一些特点:
- 1:在继承中,基类的构造(__init__()方法)不会被自动调用,派生类需要另外定义构造。
- 2:派生类在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。在类中调用普通函数时并不需要带上self参数。
- 3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个从左至右搜索查找。(先在本类中查找调用的方法,找不到才去基类中找)
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 self.__private_methods
异常处理
程序运行会遇到各种各样的错误,有的错误是是程序编写问题,是bug,需要修复;有的错误是用户输入导致,可以通过输入检查来解决。但有一类错误是完全无法在程序运行过程中预测的,比如写入文件的时候,磁盘满了,写不进去了,或者从网络抓取数据,网络突然断掉了。这类错误也称为异常
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。一般情况下,在Python无法正常处理程序时就会发生一个异常。当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
捕捉异常可以使用try/except语句。try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。
try....except...else的语法
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
- 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
- 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
- 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
#!/usr/bin/python # -*- coding: UTF-8 -*- try: fh = open("testfile", "w") fh.write("This is a test file for testing except!") except IOError: print "Error: no file found or no read right" else: print "write file successfully" fh.close()
使用except而不带任何异常类型, 会捕获所有发生的异常。但这不是一个很好的方式,我们不能通过该程序识别出具体的异常信息。因为它捕获所有的异常。
try: 正常的操作 ...................... except: 发生异常,执行这块代码 ...................... else: 如果没有异常执行这块代码
使用except而带多种异常类型。可以使用相同的except语句来处理多个异常信息,如下所示:
try: 正常的操作 ...................... except(Exception1[, Exception2[,...ExceptionN]]]): 发生以上多个异常中的一个,执行这块代码 ...................... else: 如果没有异常执行这块代码
try....except...else...finally的语法
finally 语句无论是否发生异常都将执行最后的代码。
try: x = int(input('input x:')) y = int(input('input y:')) print('x/y = ',x/y) except ZeroDivisionError: print("ZeroDivision") except (TypeError,ValueError,SyntaxError) as e: print(e) except: print("it's still wrong") else: print('it work well') finally: print("Cleaning up")
异常的参数
一个异常可以带上变量参数,可作为输出的异常信息参数。
你可以通过except语句来捕获异常的参数,如下所示:
try: 正常的操作 ...................... except ExceptionType, Argument: print(Argument)
从Python2.6开始,又开始支持另外一种写法,如下。Python3.0中只支持下面的写法。
try: 正常的操作 ...................... except ExceptionType as Argument: print(Argument)
触发异常
可以使用raise语句自己触发异常, raise语法格式如下:
raise [Exception [, args ]]
raise IOError, "file error"
Python 2.6开始,还支持另外一种带括号写法,如下。Python3.0中也只支持下面的写法。
raise Exception(args) 或 raise Exception
raise IOError("file error")
用户自定义异常
通过创建一个新的异常类,程序可以命名它们自己的异常。异常应该是典型的继承自Exception类,通过直接或间接的方式。
Python 标准异常
Python 命令行运行时带参数
例如有一个python文件sample.py,命令行带参数运行:python sample.py --version,运行结果为Version 1.2
import sys def readfile(filename): '''Print a file to the standard output.''' f = file(filename) while True: line = f.readline() if len(line) == 0: break print line, f.close() print "sys.argv[0]---------",sys.argv[0] print "sys.argv[1]---------",sys.argv[1] # Script starts from here if len(sys.argv) < 2: print 'No action specified.' sys.exit() if sys.argv[1].startswith('--'): option = sys.argv[1][2:] # fetch sys.argv[1] but without the first two characters if option == 'version': print 'Version 1.2' elif option == 'help': print '''" This program prints files to the standard output. Any number of files can be specified. Options include: --version : Prints the version number --help : Display this help''' else: print 'Unknown option.' sys.exit() else: for filename in sys.argv[1:]: readfile(filename)
代码中sys.argv[]是用来获取命令行参数的,sys.argv[0]表示代码本身文件路径; 这里sys.argv[0]就代表“sample.py”,所以参数从1开始,sys.argv[1]代表--version,sys.argv[1][2:]表示取参数--version,再从第三个字符开始截取到最后结尾,则结果为version
Reference