Python中的分支语句、循环语句、异常等比起其他语言要简单、精简却又实用。本篇文章对分支语句、循环语句、异常、函数的使用进行总结归纳。
1.分支语句
python中分支语句格式如下:
if bool_xxx :
....
elif bool_xxx :
...
else:
...
其中elif 可选,这和java中的else if类似。还可以将上述语句提取为单一的表达式:
expression1 if bool_xxx else expression2.
比如:
x = “many” if sum > 0 else "little"
2.循环语句
Python中提供了while
循环和for ... in
循环,格式如下:
while循坏
while bool_xxx:
...
else:
...
其中else分支可选,如果while循环正常终止,则接下来会执行else分支,如果while分支因出现异常而终止或者使用break语句终止,则不执行else分支。可以使用else语来实现list类型的类似str.find()的方法:
>>> def list_find(lst,target):
index = 0
while(index < len(lst)):
if(lst[index] == target):
break
index += 1
else:
index = -1
return index
for循坏
for循环格式如下:
for expression in iterable:
...
else:
...
和while循环类似,如果for循环正常执行终止,则会执行else语句,如果因异常和break语句终止,则不执行else语句。
3.异常
3.1.异常捕获
异常的捕获处理使用try..except
代码块实现,格式如下:
try:
......
except exceptionName [as variable]:
......
except exceptionNameGroup [as variable]:
......
else:
......
finally:
......
else语句和finally可选,as variable可选,表示将该异常赋给variable变量。常用方式为try...except...finally...
如果try语句中的代码正常执行完毕,则会执行else语句,如果出现异常、break语句终止则不会执行。finally代码块在最后执行。
如果有多个except,则应该按照子类异常——父类异常的顺序。也可以使用try...except
语句实现list的类似str.find()
方法:
>>> def list_find(lst,target):
try:
index = lst.index(target)
except ValueError:
index = -1
return index
3.2.异常抛出
除了捕获程序运行时的异常,我们还可以自己抛出一个异常,用以改变程序的运行流程,抛出异常有两种格式,如下:
raise exception(args)
raise exception(args) from SuperException
如:
>>> def myexcept():
i = 10
while(i > 0):
if(i == 5):
raise ValueError("i can't equal 5!!")
i -= 1
print(i)
>>> myexcept()
9
8
7
6
5
Traceback (most recent call last):
File "<pyshell#105>", line 1, in <module>
myexcept()
File "<pyshell#104>", line 5, in myexcept
raise ValueError("i can't equal 5!!")
ValueError: i can't equal 5!!
>>>
第二种形式用于抛出自定义异常,当然自定义异常也可以使用第一种形式抛出,如:
#自定义一个异常
>>> class MyExcept(ValueError):pass
>>> def myexcept():
i = 10
while(i > 0):
if(i == 5):
raise MyExcept("i cant equal 5 !!!") from ValueError
i -= 1
print(i)
>>> myexcept()
9
8
7
6
5
ValueError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<pyshell#117>", line 1, in <module>
myexcept()
File "<pyshell#110>", line 5, in myexcept
raise MyExcept("i cant equal 5 !!!") from ValueError
MyExcept: i cant equal 5 !!!
>>>
3.3.自定义异常
自定义异常格式如下:
class MyExcept(Exception):pass
自定义异常的父类是Exception或继承于Exception的子类。
4.函数
4.1.全局函数
函数定义格式如下:
def fun(args):
...
return v
其中参数可选,返回值也可选。
Python函数还提供了和C++中类似的默认参数的形式:
def fun(args1,args2,args=...):
...
return v
- 1.默认值参数必须是函数最后一个参数,不能在默认参数之后还有参数,比如
def myfun(x,y=2,b)
这种是错误的。 - 2.默认值是在执行def的时候创建的,而不是在定义def的时候创建,因此,对于可变类型的参数,每次调用都会重新创建,如:
>>> def add_list(x,lst=[]):
if(x % 2 == 0):
lst.append(x)
return lst
>>> for i in range(10):
my_list(i) #在for循环中调用10次,只创建了1次
[0]
[0]
[0, 2]
[0, 2]
[0, 2, 4]
[0, 2, 4]
[0, 2, 4, 6]
[0, 2, 4, 6]
[0, 2, 4, 6, 8]
[0, 2, 4, 6, 8]
如果要对可变类型参数作为默认值,可以使用如下形式,这样可以保证每次调用都会创建新的对象:
>>> def add_list(x,lst=None):
lst = []
if(x % 2 == 0):
lst.append(x)
return lst
函数的注释
在java中,可以对定义的方法进行注释,Python中也可以,使用三个"""
表示,如:
def my_fun(x,y):
""" This is a docstring
detail description
>>> my_fun(x,y)
...
"""
print(x,y)
一般使用方式是第一行为简短的描述信息,一个空白行、进一步的描述信息,最后是一些示例,这些实例可用于进行单元测试。要注意示例必须以>>>
后加一个空格开头,执行测试时只需要添加如下几行就可以执行:
if __name__ == "__main__":
import doctest
doctest.testmod()
在任何模块(即.py文件)被导入后,Python都会创建一个特殊的变量__name__
,并将模块名存储在该变量中,当.py文件运行时,Python会为该程序创建一个__mane__
的特殊变量,并将其设置为__main__
.
可以使用help(my_fun)
来查看对函数的说明。
函数参数
Python的参数传递有值传递、引用传递、关键字传递。值传递如一些基本数据类型int、float,引用传递如对象;关键字传递是指在函数调用时直接给定形参的值如:
>>>def sum(a,b,c)
>>>sum(b=2,a=1,c=3)
1.可变参数
可以在函数参数列表中使用序列拆分操作符*创建一个可变参数,格式如下:
def fun(*args):
*args表示在函数内部,参数args是一个元组,项数随着给定的位置参数个数的变化而变化,如通过可变参数求给定值的和:
>>> def sum(*item):
result = 1
for i in item:
result += i
print(result)
>>> sum(12,3,4,56)
76
这种方式的好处就是进行更简单的调用,还可以在调用函数时将可变参数作为一个实参,如果有序列类型t1,则sum(t1[0],t1[1],t1[2])可以使用sum(*t1)进行调用,比如:
# 定义一个函数
>>> def sum(a,b,c):
result = 0
result =a + b + c
print(result)
>>> sum(1,2,3)
6
>>>
>>> l = [1,2,3]
# 使用序列拆分操作符
>>> sum(*l)
6
>>>
2.默认参数
Python函数中可以使用默认参数,比如:
# 错误形式
>>> def sum(flag = 3,*item):
result = 1
for i in item:
result += i
result *= flag
print(result)
但是上例不是一个好的举例,应该将默认参数放在位置参数的后面,因为调用时可以不传入默认参数,也可以传入,如果将默认参数作为第一个参数,调用时第一个参数就赋给了默认参数。正确示例如下:
>>> def sum(*item,flag = 0):
result = 0
for i in item:
result += i
print(result)
>>> sum(1,2,3,flag = 4)
6
3.关键字参数
在函数调用时,以键值对的形式指定形参值叫做关键字参数,如:
#定义一个函数
>>> def show(id,name):
print("id:{}".format(id))
print("name:{}".format(name))
# 使用关键字参数调用函数
>>> show(id=2,name="zhangsan")
id:2
name:zhangsan
>>>
4.*作为参数
可以将*
直接作为函数参数,表示在*
后不能出现位置参数,但可以出现关键字参数:
>>> def sum(*args,*) #说明不能和可变参数一起使用
SyntaxError: invalid syntax
>>>
>>> def sum(a,b,c,*,flag = 2):
return (a+b+c)*flag
>>> sum(1,2,3)
12
>>> def sum(a,b,c,*,d,flag = 2):
return (a+b+c)*flag
>>> sum(1,2,3,4)
# 在`*`后使用了一个d参数,但在调用时出现TypeError异常。
Traceback (most recent call last):
File "<pyshell#60>", line 1, in <module>
sum(1,2,3,4)
TypeError: sum() takes 3 positional arguments but 4 were given
>>>
因此,如果*
作为第一个参数,那么不允许使用任何的位置参数(可以使用关键字参数)。
5.**包裹关键字
通过序列拆分符*
可以将序列类型的值作为参数,并使用序列类型名进行调用,同样地,可用通过映射拆分操作符**
将一个字典类型的值作为参数进行调用。如:
# 定义一个函数
>>> def show(**kwargs):
for key in kwargs:
print(key,kwargs.get(key))
调用该函数时:
>>> d = dict(id = 1,name="zhangan",age = 12)
>>> show(**d)
id 1
age 12
name zhangan
或者将函数定义为如下形式:
>>> def show(id = 1,name = "z",age = 3):
print("id :{0}".format(id))
print("name:{0}".format(name))
print("age:{0}".format(age))
调用时:
>>> show()
id :1
name:z
age:3
>>> show(**d)
id :1
name:zhangan
age:12
>>>
当然前提是d的key和函数形参匹配,否则会出现TypeError异常。
**
作为函数参数时,是映射拆分操作符,还可以作为幂运算符。a**b表示a的b次方。
4.2.Lambda函数
Lambda函数格式如下:
lambda [parameter] : expression
- parameter可选,通常是以逗号分割的变量名,可以理解为位置参数。
- expression语句中不能包含分支、循环、return、yield。
- 如果expression是一个元组,必须使用()将其括起来。
- 返回值为对表达式计算的结果。
如:
>>> s = lambda x:"yes" if x>=0 else "no"
>>> s(12)
'yes'
>>> s(-1)
'no'
Lambda用法
- 1.Lambda函数可以在sorted()函数和list.sort()函数中用作键值对,指定其排序顺序,如:
>>> elsments = [(1,11,"S"),(2,10,"T"),(3,9,"L")]
>>> sorted(elsments)
[(1, 11, 'S'), (2, 10, 'T'), (3, 9, 'L')]
>>>
>>> sorted(elsments,key=lambda e:(e[1],e[2]))
[(3, 9, 'L'), (2, 10, 'T'), (1, 11, 'S')]
- 2.Lambda函数可以在创建默认字典时使用:
>>> import collections
>>> d1 = collections.defaultdict(lambda:1) #将Lambda理解为普通函数,返回值为表达式计算结果,即1
>>> d1["xxx"]
1
assert断言
断言是用来提示错误信息的一种测试方式,其语法格式如下:
assert boolean_expression,information
如果boolean_expression为False,则会产生一个AssertionError异常,并将information作为异常的信息,下面是一个使用断言的例子:
def divide(i, j):
assert (j != 0), "can't divide zero"
return i // j
if __name__ == "__main__":
s = divide(2, 0)
print(s)
运行结果如下:
D:\ProgramFiles\Python\Pyton3\python.exe E:/PythonWorkSpace/opt.py
Traceback (most recent call last):
File "E:/PythonWorkSpace/opt.py", line 6, in <module>
s = divide(2, 0)
File "E:/PythonWorkSpace/opt.py", line 2, in divide
assert (j != 0), "can't divide zero"
AssertionError: can't divide zero
断言是为开发者而设计,而不是面向终端用户的。因此,在程序发布后,应注释掉断言,或者不执行断言语句,有两种方式:
- 1.python3 -O program.py
- 2.将环境变量PYTHONOPTIMIZE配置为O