首页 > 代码库 > python 学习笔记day06-错误和异常、函数基础

python 学习笔记day06-错误和异常、函数基础

错误和异常

    基本概念

        错误

            从软件方面来说,错误是语法或是逻辑上的

            - 语法错误指示软件的结构上有错误,导致不能被解释器解释或编译器无法编译,这些错误必须在程序执行前纠正

            - 逻辑错误可能是由于不完整或是不合法的输入所致,还可能十逻辑无法生成、计算,或是输出结果需要的无法执行

        异常

            当python检测到一个错误时,解释器就会指出当前流已经无法继续执行下去,这时候就出现了异常        

            异常是因为程序出现了错误而在正常控制流以外采取的行为

            这个行为又分为两个阶段:

            - 首先是引起异常发生的错误

            - 然后是检测(和采取可能的措施)阶段

        python中的异常

            当程序运行时,因为遇到未解的错误而导致终止运行,便会出现tarceback消息,打印异常

异常
描述
NameError
未声明/初始化对象
IndexError
序列中没有此索引
SyntaxError
语法错误
KeyboardInterrupt
用户中断执行
EOFError
没有内建输入,到达EOF标记
IOError
输入/输出操作失败

    检测和处理异常

        try.except语句

            定义了进行异常监控的一段代码,并且提供了处理异常的机制

            try:

                try_suite #监控这里的异常

            except Exception[,reason]

                except_sutie # 异常处理代码

                >>> try:
                ...   f = open(‘foo.txt‘)
                ... except IOError:
                ...   print "No such file!"
                ...
                No such file!

                #!/usr/bin/env pytyon

                import time

                for i in range(1,11):
                    print i
                    try:

                         time.sleep(1)
                    except KeyboardInterrupt:
                         break/pass
                 print ‘done‘


        带有多个except的try语句

            可以把多个except语句连接在一起,处理一个try块中可能发生的多种异常

            

                >>> try:

                ...   data = http://www.mamicode.com/int(raw_input(‘input a number: ‘))

                ... except KeyboardInterrupt:    

                ...   print ‘user cancelled‘

                ... except ValueError:

                ...   print ‘you must input a number!‘   

                ... 

                input a number: hello

                you must input a number!

习题训练:简化除法判断

    编写除法程序

    1、提示用户输入一个数字作为除数

    2、如果用户按下Ctrl+C或Ctrl+D则退出程序

    3、如果用户输入非数字字符,提示用户应该输入数字

    4、如果用户输入0,提示用户0不能作为除数

#!/usr/bin/env python


try:

    num = int(raw_input(‘number: ‘))

    result = 100 / num

except (KeyboardInterrupt,EOFError):

    print "User cancelled"

except (ValueError,ZeroDivisionError):

    print "Invalib input!"

        捕获所有异常

            如果出现的异常没有出现在指定要捕获的异常列表中,程序仍然会中断,可以使用

            在异常继承的树结构中,BaseException实在最顶层的,所以使用它可以捕获任意类型的异常

                >>> try:

                ...   data = http://www.mamicode.com/int(raw_input("input a number: "))

                ... except BaseException:

                ...   print "\nsome error"

                ... 

                input a number: ^C

                some error

        异常参数

            异常也可以有参数,异常引发后它会被传递给异常处理器

            当异常被引发后参数是你为附加帮助信息传递给异常处理器的

                >>> try:

                ...   data = http://www.mamicode.com/10 / 0

                ... except ZeroDivisionError,e:  

                #异常名字(如果有多个用()括起来,用逗号隔开),第二个参数是存储异常原因的变量

                ...   print "Error",e

                ... 

                Error integer division or modulo by zero

        else子句

            在try范围中没有异常被检测到时,执行else子句

            在else范围中的任何代码运行前,try范围中的所有代码必须完全成功

            

                >>> try:

                ...   res = 10 / int(raw_input("Input a number: "))

                ... except BaseException,e:

                ...   print "Error:",e

                ... else:

                ...   print res

                ... 

                Input a number: 5

                2

        finally子句

            finally子句是无论异常是否发生,是否捕捉都会执行的一段代码

            如果打开文件后,因为发生异常导致文件没有关闭,可能会发生数据损坏。使用finally可以保证文件总是能正常关闭

                >>> try:
                ...   try:
                ...     ccfile = open(‘carddata.txt‘,‘r‘)
                ...     txns = ccfile.readlines()
                ...   except IOError:
                ...     log.write("no txns this month\n")
                ... finally:
                ...   if ccfile:
                ...     ccfile.close()
                ...
f = open(‘abc.txt‘,‘r‘)

try:

  data = http://www.mamicode.com/f.read()

finally:

  f.close()

        with子句

            with语句是用来简化代码的

            在将打开文件的操作放在with语句中,代码块结束后,文件将自动关闭

                >>> with open("get-pip.py") as f:
                ...   data = http://www.mamicode.com/f.readlines()
                ...
                >>> f.closed
                True


    触发异常

        raise语句

            要想引发异常,最简单的形式就是输入关键字raise,后面跟要引发的异常的名称

            执行raise语句时,Python会创建指定的异常类的一个对象

            raise语句还可指定对异常对象进行初始化的参数

                >>> number = 3
                >>> try:
                ...   if number < 10:
                ...     raise ValueError,‘Number is too smalle.‘  #(必须是系统存在的异常,可自定义异常产生原因)
                ... except ValueError,e:
                ...   print ‘Error:‘,e
                ...
                Error: Number is too smalle.


        断言

            断言是一句必须等价于布尔值为真的判定

            此外,发生异常也意味着表达式为假

                >>> number = 3
                >>> try:
                ...   assert number > 10,‘number is too small‘
                ... except AssertionError,e:
                ...   print ‘Error:‘,e
                ...
                Error: number is too small
函数基础

    创建函数

        def语句

            函数用def语句创建,语法如下:

            def function_name(arguments):

                "function_documentation_string"

                function_body_sutie

            标题行由def关键字,函数的名字,以及参数的集合(如果有的话)组成

            def子句的剩余部分包括了一个虽然可选但是强烈推荐的文档字串,和必须的函数体

        前向引用

            函数不允许在函数未声明之前对其引用或者调用

            def foo():

                print "in foo"

                bar()

            foo()    #报错,因为bar没有定义

            ---------------------------------------------

            def foo():

                print “in foo”

                bar()

            def bar():

                print "in bar"

            foo() # 正常执行,虽然bar的定义在foo定义后面

        函数属性

            函数属性是python另外一个使用了句点属性标识并拥有名字空间的领域

            >>> def foo():
            ...   ‘foo() -- properly create doc string‘
            ...
            >>> foo.__doc__
            ‘foo() -- properly create doc string‘
            >>> foo.version = 1.0
            >>> foo.version
            1.0

        内部函数

            在函数体内创建另外一个函数是完全合法的,这种函数叫做内部/内嵌函数

            >>> def foo():
            ...   def bar():
            ...     print ‘bar() is called‘
            ...   print ‘foo() is called‘
            ...   bar()
            ...
            >>> foo()
            foo() is called
            bar() is called
            >>> bar()
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            NameError: name ‘bar‘ is not defined


    调用函数

        函数操作符

            使用一对圆括号()调用函数,如果没有圆括号,只是对函数的引用

            任何输入的参数都必须放置在括号中

            >>> def foo():
            ...   print "hello world!"
            ...
            >>> foo()
            hello world!
            >>> foo
            <function foo at 0xb70a2bc4>

####引用:当你定义一个函数的时候,在内存中会分配一块内存,函数名指向这块内存,此为函数引用,当你在把foo 赋值给一个变量,这个变量的作用和foo是一样的。都是指向的一块内存地址

####调用:即执行函数体中的语句,将foo()赋值给b,foo() 函数中的函数体会被执行,b得到的是foo()函数的return结果,如果在函数中没有显示定义return,则返回none,此时b的值即为none。

        关键字参数

            关键字参数的概念仅仅针对函数调用

            这种理念是让调用者通过函数调用中的参数名字来区分参数

            这种规范允许参数确实或者不按顺序

            >>> def getinfo(name,age):
            ...   print "%s ‘s age is %s" % (name,age)
            ...
            >>> getinfo(23,‘bob‘)
            23 ‘s age is bob
            >>> getinfo(age=23,name = ‘bob‘)
            bob ‘s age is 23


        参数组

            python允许程序员执行一个没有显示定义参数的函数

            相应的方法是通过一个把元组(非关键字参数)或字典(关键字参数)作为参数组传递给函数

            func(*tuple_grp_nonkv_args,**dict_grp_kw_args)

            >>> def foo(*args):
            ...   print args
            ...
            >>> foo()
            ()
            >>> foo(10)
            (10,)
            >>> foo(10,20,‘hello‘)
            (10, 20, ‘hello‘)

            >>> def add(x,y):
            ...   return x + y
            ...
            >>> add(10,20)
            30
            >>> add([10,20])
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            TypeError: add() takes exactly 2 arguments (1 given)
            >>> add(*[10,20])  #“解开”
            30

            >>> def bar(**args):
            ...   print args
            ...
            >>> bar(name=‘bob‘,age=20)
            {‘age‘: 20, ‘name‘: ‘bob‘}
            >>> bar()
            {}

            >>> def func1(args,*non_kwagrs,**kwargs):
            ...   print args
            ...   print non_kwagrs
            ...   print  kwargs
            ...
            >>> func1()
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            TypeError: func1() takes at least 1 argument (0 given)
            >>> func1(10)
            10
            ()
            {}
            >>> func1(10,20,30,name=‘bb‘)
            10
            (20, 30)
            {‘name‘: ‘bb‘}
习题训练:数学游戏

    编写一个简单的加减法数学游戏

    1、随机生成两个100以内的数字

    2、随机选择家法或是减法

    3、总是是用大的数字减去小的数字

    4、如果用户打错三次,程序给出正确答案

#!/usr/bin/env python


import random


def add(x,y):

    return x + y

def sub(x,y):

    return x - y


def probe():

    CMDs = {‘+‘: add,‘-‘: sub}

   #CMDS = {‘+‘: lambda x,y: x + y,‘-‘: lambda x,y: x-y} #可以不用定义上面的两个函数,简化代码

    nums = [random.randint(1,50) for i in range(2)]

    nums.sort(reverse=True)

    op = random.choice(‘+-‘)

    answer = CMDs[op](*nums)

    prompt = "%s %s %s = " % (nums[0],op,nums[1])

    tries = 0


    while tries < 3:

        try:

            result = int(raw_input(prompt))

        except:

            continue

        

        if answer == result:

            print "Very good!!!"

            break

        print "Wrong answer."

        tries += 1

    else:

        print "\033[31;1m%s%s\033[0m" %(prompt,answer)

if __name__ == ‘__main__‘:

    while True:

        probe()

        try:

            yn = raw_input("Continue(y/n)? ").strip()[0]

        except(KeyboardInterrupt,EOFError):

            print "\nBye-Bye"

            yn = ‘n‘

        except IndexError:

            continue

        if yn in ‘Nn‘:

            break

    匿名函数

        lambda

            python允许lambda关键字创造匿名函数

            匿名是因为不需要以标准的def方式来声明

             一个完成的lambda“语句”代表了一个表达式,这个表达式的定义体必须和声明放在同一行

            lambda[arg1[,arg2,...argN]]:expression

            

            >>> a = lambda x,y:x + y

            >>> print a(3,4)

            7

            应用实例见上面的数学游戏程序

        filter()函数

            filter(func,seq):调用一个布尔函数func来迭代遍历每个序列中的元素;返回一个使func返回值为true的元素的序列

            如果布尔函数比较简单,直接使用lambda匿名函数就显得非常方便了

            

            >>> data = http://www.mamicode.com/filter(lambda x: x % 2,[num for num in range(10)])

            >>> print data

            [1, 3, 5, 7, 9]

        map()函数

        reduce()函数

            reduce(func,seq[,init]):将二元函数作用于seq序列的元素,每次携带一对(先前的结果以及下一个序列元素),连续的将现有的结果和下一个给值作用在获得的随后的结果上,最后减少序列为一个单一的返回值

            

            >>> data = http://www.mamicode.com/reduce(lambda x,y: x + y,range(1,6))

            >>> print data

            15

习题训练:

家庭理财系统

记账:    

本文出自 “linux服务器” 博客,请务必保留此出处http://sailq21.blog.51cto.com/6111337/1860808

python 学习笔记day06-错误和异常、函数基础