zoukankan      html  css  js  c++  java
  • python0.10-----变量作用域和异常

    变量的作用域:也可以称为命名空间,即变量可以使用的范围。程序的变量并不是在所有的位置都能使用的,访问的权限决定于变量在哪里赋值(定义)的。只有当变量在模块,类,函数中定义的时候,才会有作用域的概念。if分支结构,for-else,while,for遍历循环结构,try-except(-else) ry-except-finally等关键字语句块不会产生作用域。

     

    局部变量与局部作用域:

    #定义函数

    def discount(price,rate)

      final_price=price*rate

      return final_price

    #调用函数

    new_price=discount(price=10,rate=0.5)

    print(final_price)

    解读:当执行discount(price=10,rate=0.5)这个函数调用语句时,系统就会在栈空间里开辟内存,定以变量price,rate,final_price并给它们赋值。调用结束后,也就是discount(price=10,rate=0.5)语句结束时,变量price,rate,final_price会被自动清除,因此上面print(final_price)这个访问局部变量的语句会引发异常NameError:name ‘final_price’ is not defined。可以把price,rate,final_price变量作用的范围成为局部作用域(local)。

     

    全局变量与全局作用域:

    def func():       

      b=2     #当给b赋值时,由于屏蔽机制,在栈空间中创建局部变量b。

      print(b)  #在函数中访问局部变量,大小为2。

    b=1  #这里的b是全局变量 ,大小为1。

    func()  #调用函数

    解读:全局变量b的作用范围是整个模块的代码块(称为全局作用域),在局部函数中可以随意访问全局变量b。在函数内试图修改全局变量b时,python使用屏蔽机制,函数会屏蔽全局变量b,在栈区域定义一个名叫b的局部变量,两个变量虽然名字相同,但是它们在内存中的位置不一样,它们不一样!!!

    注意:可以使用global关键字在函数内部修改或者创建全局变量。但是建议不要这么做,因为它会使程序可读性变差,程序很难维护,做为函数尽自己的本分就好。例如:

    def func():

      global b  #屏蔽机制失效,可以在函数内操纵全局变量

      b=2

    print(b)  #在函数中访问全局变量

    b=1  #全局变量

    print(b)  #此时b的值还是1

    func()  #调用函数

    print(b)  #此时b的值被func函数改成2了

     

    外部变量与嵌套作用域:

    在解释这个概念前先引入闭包的概念:

    闭包(closure):python中闭包从表现形式上定义为:如果在一个内部函数里,对外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就会被认为是闭包(closure)。

    外部变量和嵌套作用域:

    def FunX(x):

      def FunY(y):

        return x*y

      return FunY

    解读:对于FunY来说,FunX就是外部作用域,x是外部作用域的变量,FunY是内部函数,并且FunY函数引用了这个变量x。符合这两个条件,那么可称内部函数FunY就是一个闭包。事实上,这里说的外部作用于就是嵌套作用域(enclosing)。全局范围内,不能调用FunY。局部变量作用于外部变量,跟之前局部变量作用于全局变量一样。局部变量可以访问外部变量,但不能直接修改外部变量,若修改,则屏蔽机制生效,在闭包中创建局部变量,并且不影响外部变量。

    def FunX(x):  #x为外部变量

      def FunY(y): #y为局部变量,FunY为闭包

        x=1  #当给x赋值时,由于屏蔽机制,在栈空间中创建局部变量x,不影响外部变量x。

        return x*y

      return FunY

     

    若执意修改,采用nonlocal的关键字进行修改。但是建议不要这么做,因为它会使程序可读性变差,程序很难维护,做为闭包尽自己的本分就好。

    例子:

    def FunX(x):  #x为外部变量

      def FunY(y):  #y为局部变量,FunY函数为闭包

        nonlocal x #声明操作的x为外部变量

        x=1  #现在外部变量x的值为1。

        return x*y

      return FunY

     

     

     

    异常处理:

    一般来说编码错误叫做bug。而不是由于编码错误产生,而是由于用户操作失误,程序运行会报错,这叫做异常。程序可预测的错误,例如存储空间不足,网络错误,也叫做异常。若程序出现问题,希望程序越过错误,不要停止执行。此时可以用异常处理技术。

    异常处理的结构有2种:分为try-execpt(-else),try-except-finally

     

    try-execpt(-else):

    格式:

    try:

      语句t

    except 异常码1 as e:

      语句1

    except 异常码2 as e:

      语句2

    ………………

    except 异常码n as e:

      语句n

    else:   #else语句可有可无

      语句e

     

    逻辑:

    1:系统检测try语句块中的语句t是否有异常,而异常的类型是多种多样的,不同的异常对应不同的异常码,发生异常时,except捕获对应的异常码,执行相应的异常处理语句。

    2:若系统检测try语句块中的语句t出现异常,但是没有捕获相应的异常码,那么异常会被提交到上一层的try语句,或者到程序的最上层。

    3:若系统检测try语句块中的语句t没有出现异常,则执行else分支下的语句e。

    4:详细的错误原因会放到e中,e为字符串类型。

     

    善变的try-execpt(-else)之一:

    #使用except而不使用任何的异常类型,这个很常用。因为查异常类型很麻烦,而且也很难处理。

    try:

      语句t

    except :

      语句e

     

    善变的try-execpt(-else)之二:

    #使用except带着多种异常

    try:

      语句t

    except (NameError,ZeroDivisionError):

      语句e

    解释:若出现了NameError,ZeroDivisionError,都会在except里面处理。

     

    try-except-finally:

    格式:

    try:

      语句t

    except 异常码1 as e:

      语句1

    except 异常码2 as e:

      语句2

    ………………

    except 异常码n as e:

      语句n

    finally:

      语句e

    #不管语句t有没有出错,语句e必定执行。

    用处:在文件处理中,应该使用finally,因为文件读写的过程中,不管读写过程是否出错,文件的关闭必须要执行,因此这里非常适合finally来使用。

     

    异常机制还需注意:

    #1 .异常其实是class类,所有的错误都继承自BaseExeception。所以在捕获的时候,它捕获了该类型的异常,还把子类的异常一网打尽。

    #2.若内存存满了,需要在异常处理里面释放一部分内存。

    #3.跨多层调用,main()调用func2,func2调用func1,只要调用main()时补获了异常,就可以处理,程序可以不停止运行。

    例如:
    #定义

    def func1(num):

      print(1/num)

    def func2(num):

      func1(num)

    def main():

      func2(0)

     

    try:

      main()   #调用

    except ZeroDivision as e:

      语句e

     

    断言(assert):

    格式:

    assert 表达式,’异常提示’ 

    解释:当表达式为真时,不会出现异常提示。当表达式为假时,会抛出assert异常,异常类型后面可以跟随自己编写的‘异常提示’,‘异常提示’可要可不要。当然assert抛出的异常也是可以捕获的。但是assert一定要在try里面使用,并且表达式的格式一定要正确,异常提示会赋值给e。

    例如:

    try:

      assert 2==1,'我好快乐'

    except BaseException as e:

      print('发生错误',e)

    else:

      print('没有发生错误')

    #输出:

    发生错误 我好快乐

     

     

    标准异常名称 描述

    BaseException 所有异常的基类

    SystemExit 解释器请求退出

    KeyboardInterrupt 用户中断执行(通常是输入^C)

    Exception 常规错误的基类

    StopIteration 迭代器没有更多的值

    GeneratorExit 生成器(generator)发生异常来通知退出

    SystemExit Python 解释器请求退出

    StandardError 所有的内建标准异常的基类

    ArithmeticError 所有数值计算错误的基类

    FloatingPointError 浮点计算错误

    OverflowError 数值运算超出最大限制

    ZeroDivisionError 除(或取模)零 (所有数据类型)

    AssertionError 断言语句失败

    AttributeError 对象没有这个属性

    EOFError 没有内建输入,到达EOF 标记

    EnvironmentError 操作系统错误的基类

    IOError 输入/输出操作失败

    OSError 操作系统错误

    WindowsError 系统调用失败

    ImportError 导入模块/对象失败

    KeyboardInterrupt 用户中断执行(通常是输入^C)

    LookupError 无效数据查询的基类

    IndexError 序列中没有没有此索引(index)

    KeyError 映射中没有这个键

    MemoryError 内存溢出错误(对于Python 解释器不是致命的)

    NameError 未声明/初始化对象 (没有属性)

    UnboundLocalError 访问未初始化的本地变量

    ReferenceError 弱引用(Weak reference)试图访问已经垃圾回收了的对象

    RuntimeError 一般的运行时错误

    NotImplementedError 尚未实现的方法

    SyntaxError Python 语法错误

    IndentationError 缩进错误

    TabError Tab 和空格混用

    SystemError 一般的解释器系统错误

    TypeError 对类型无效的操作

    ValueError 传入无效的参数

    UnicodeError Unicode 相关的错误

    UnicodeDecodeError Unicode 解码时的错误

    UnicodeEncodeError Unicode 编码时错误

    UnicodeTranslateError Unicode 转换时错误

    Warning 警告的基类

    DeprecationWarning 关于被弃用的特征的警告

    FutureWarning 关于构造将来语义会有改变的警告

    OverflowWarning 旧的关于自动提升为长整型(long)的警告

    PendingDeprecationWarning 关于特性将会被废弃的警告

    RuntimeWarning 可疑的运行时行为(runtime behavior)的警告

    SyntaxWarning 可疑的语法的警告

    UserWarning 用户代码生成的警告

  • 相关阅读:
    OGRE源代码resource分析
    全排列
    各种让人无语的库
    python Kmeans算法
    Linux服务器安装MariaDB数据库
    初探SEO,BSP收录速度测试
    MetaWeblog API调用
    Patterns
    腾讯。。。对Linux的支持程度直接扼杀了Linux在国内用户群的增长
    个人电子商务网站建设之——整站静态化实现的选择、设计与实现(二):静态页面的实现方式;
  • 原文地址:https://www.cnblogs.com/yulianggo/p/9201681.html
Copyright © 2011-2022 走看看