[Python] Python流程控制、异常、函数

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值