资源简介 (共61张PPT)单元6类的定义与使用Python程序设计知识入门知识要点1.Python 3 面向对象技术简介 2.Python 身份运算符1.Python 3 面向对象技术简介(1)类(Class)在Python 中,类是一个抽象概念,例如学生、职工、教师、学校、班级、图书、电子产品、手机、电视机、西装等客观实体都可以在程序中定义为对应的类,在类中,可以定义每个对象共有的属性和方法,类是用来描述具有相同的属性和方法的对象的集合。(2)实例化(3)对象创建一个类的实例,即创建类的具体对象,也称为实例化。对象是事物存在的实体,类定义完成后就会产生一个类对象。对类进行实例化操作,创建一个类的实例,就会产生类的实例对象,实例对象是根据类的模板生成的一个内存实体,有确定的数据与内存地址。1.Python 3 面向对象技术简介(4)数据成员类主要包括两类数据成员:属性和方法。类定义了集合中每个对象共有的属性和方法。在类的声明中,属性是用变量来表示的,方法是指在类中定义的函数。(5)类属性(6)实例属性实例属性用来描述根据类创建的实例对象,通过实例属性或者self 变量可以给实例绑定属性。实例属性是指定义在方法内部的属性,通常在类的__init__() 方法内部定义,在各自实例对象的内存中都保存一份,只能通过实例名称而不能通过类名称访问实例属性。也可以通过实例名称修改实例属性值。描述类的属性称为类属性,它属于类。如果类本身需要绑定一个属性,可以直接在类中定义属性,这种属性是类属性,归类所有。类属性在内存中只有一份,所有实例对象公用,类的所有实例都可以访问。1.Python 3 面向对象技术简介(7)方法方法是指类中定义的函数,通常也分为实例方法和类方法。实例方法是在类中使用def关键字定义的函数,至少有一个参数,一般以名为“self ”的变量作为参数(使用其他名称也可以),而且需要作为第一个参数,实例方法一般使用实例名称调用。类方法是属于类的方法,这种方法要使用@classmethod 来修饰,其第一个参数一般命名为cls(也可以是别的名称)。类方法一般使用类名称调用。(8)继承(9)方法重写如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(Override),也称为方法的重写。继承是指派生类(Derived Class)继承父类(Base Class)的属性和方法,允许把一个派生类的对象作为一个父类对象。2.Python 身份运算符运算符 说明 实例is is是判断两个标识符是不是引用自同一个对象 x is y,类似id(x) == id(y)。如果引用的是同一个对象则返回True,否则返回Falseis not is not是判断两个标识符是不是引用自不同对象 x is not y,类似id(a) != id(b)。如果引用的不是同一个对象则返回结果True,否则返回False。【说明】表6-1 中的id() 函数用于获取对象的内存地址。is 与== 的区别是:is 用于判断两个变量的引用对象是否为同一个,== 用于判断引用变量的值是否相等。循序渐进知识要点6.1 创建类及其对象 6.1.2 创建类的实例 6.2 类属性与实例属性 6.3 类方法与实例方法 6.3.1 类的实例方法 6.3.2 类方法 6.3.3 静态方法6 【任务6-1】定义商品类及其成员 【任务6-2】修改与访问类属性、创建实例属性 【任务6-3】定义与访问类的实例方法6.4 类的构造方法与析构方法6.4.1 类的构造方法6.4.2 类的析构方法6.5 类的继承与方法重写6.5.1 类的继承6.5.2 方法继承6.5.3 方法重写6.6 Python 3的命名空间和作用域6.1.1 定义类在Python 中,类的定义使用class 关键字来实现,定义类的基本语法格式如下。class ClassName: # 类体其中,ClassName 用于指定类名称,一般使用大写字母开头,如果类名称中包括多个单词,后面的几个单词的首字母也要大写,即采用大驼峰法命名,这是类的命名惯例,应遵守;statement 表示类体,类体主要包括类属性定义和方法定义。如果在定义类时,暂时不需要编写代码,也可以在类体中直接使用pass 语句代替实际的代码。【注意】类名称后有个冒号,类体要向右边合理缩进。6.1.2 创建类的实例类定义完成后,并不会真正创建一个实例对象,还需要手动创建类的实例,即实例化类。类的实例化也称为创建对象,其基本语法格式如下。ClassName(parameterlist)其中,ClassName 是必选名称,用于指定具体的类名称;parameterlist 是可选参数,当创建一个类时没有创建__init__() 方法,或者当__init__() 方法中只有一个self 参数时,parameterlist 允许省略。6.1.2 创建类的实例【实例6-1】演示Python 类的定义与类实例的创建实例6-1 的代码如下所示。实例6-1 代码的运行结果如下。循序渐进知识要点6.1 创建类及其对象 6.1.2 创建类的实例 6.2 类属性与实例属性 6.3 类方法与实例方法 6.3.1 类的实例方法 6.3.2 类方法 6.3.3 静态方法6 【任务6-1】定义商品类及其成员 【任务6-2】修改与访问类属性、创建实例属性 【任务6-3】定义与访问类的实例方法6.4 类的构造方法与析构方法6.4.1 类的构造方法6.4.2 类的析构方法6.5 类的继承与方法重写6.5.1 类的继承6.5.2 方法继承6.5.3 方法重写6.6 Python 3的命名空间和作用域6.2 类属性与实例属性类的成员包括属性和方法,在类中创建了类的成员后,可以通过类的实例进行访问。在类中定义的变量称为类的属性,根据定义位置的不同,属性可以分为类属性和实例属性。类实例化后,可以使用其属性,实际上,创建一个类之后,就可以通过类名称访问其属性。类属性是指在类中的方法外定义的属性,包括公有属性、保护属性和私有属性,类属性可以在类的所有实例之间共享,也就是在所有实例化的对象中公用。实例属性在方法内定义,通常在类的__init__() 方法中定义,实例属性只属于类的实例,只能通过实例名称访问。6.2 类属性与实例属性【实例6-2】演示Python 类的定义与类属性的定义实例6-2 的代码如下所示。实例6-2 代码的运行结果如下。6.2 类属性与实例属性实例6-2 中的属性style、model、clothingLength、bust、waistline、leeveLength、shoulderWidth都属于Suit 类的属性,这些属性在类中的方法外面、方法内部、类外部都可以访问,但访问形式有区别,如表所示。访问位置 访问形式与要求 样例类内部 方法外部 属性名称 style类内部 方法内部 类名称.属性名称 Suit.bust、Suit.modelself.属性名称 self.style类外部 类名称.属性名称 Suit.bust类实例名称.属性名称 suit1.model由表6-2 可知,类属性的访问形式有4 种:属性名称、类名称. 属性名称、self. 属性名称、类实例名称. 属性名称。6.2 类属性与实例属性因为类属性可以在类的所有实例之间共享,如果在类外对类属性进行修改,所有类实例的属性也会同步修改,类属性的值通过多个类实例访问时,其结果相同。suit2=Suit()Suit.bust=60.5print("Suit 类的属性bust 值为:", Suit.bust)print("suit1 实例的属性bust 值为:", suit1.bust)print("suit2 实例的属性bust 值为:", suit2.bust)在实例6-2 中添加以下代码。新增代码的运行结果如下。Suit 类的属性bust 值为: 60.5suit1 实例的属性bust 值为: 60.5suit2 实例的属性bust 值为: 60.5从运行结果可以看出,通过3 种方式(Suit.bust、suit1.bust、suit2.bust)访问类属性,其结果均为修改后的属性值。如前所述,衬衫设计图相当于类,其属性值修改后,所有根据修改后的设计图制作的衬衫实物,其属性值会同步变化。6.2 类属性与实例属性suit2.bust=59.5print("Suit 类的属性bust 值为:", Suit.bust)print("suit1 实例的属性bust 值为:", suit1.bust)print("suit2 实例的属性bust 值为:", suit2.bust)在实例6-2 中添加以下代码。第2 次新增代码的运行结果如下。Suit 类的属性bust 值为: 60.5suit1 实例的属性bust 值为: 60.5suit2 实例的属性bust 值为: 59.5从第2 次新增代码的运行结果可以看出,通过类实例suit2 修改bust 属性值后,只有类实例suit2 的bust 属性值发生了变化,而类Suit 的bust 属性值和另一个类实例suit1 的bust属性值都没有改变。这里修改的bust 属性是类实例suit2 的属性,而不是类Suit 的属性。根据以上分析可知,实例属性也可以通过实例名称进行修改,与类属性不同,通过实例名称修改实例属性后,并不影响类属性和其他实例中相应的实例属性的值,影响的只有实例自身的属性值。循序渐进知识要点6.1 创建类及其对象 6.1.2 创建类的实例 6.2 类属性与实例属性 6.3 类方法与实例方法 6.3.1 类的实例方法 6.3.2 类方法 6.3.3 静态方法6 【任务6-1】定义商品类及其成员 【任务6-2】修改与访问类属性、创建实例属性 【任务6-3】定义与访问类的实例方法6.4 类的构造方法与析构方法6.4.1 类的构造方法6.4.2 类的析构方法6.5 类的继承与方法重写6.5.1 类的继承6.5.2 方法继承6.5.3 方法重写6.6 Python 3的命名空间和作用域6.3.1 类的实例方法创建类的实例方法的基本语法格式如下。def functionName( self , parameterlist )< 方法体>functionName 表示方法名称,采用小驼峰法命名,使用小写字母开头。self 为必要参数,表示类的实例,可以通过它来传递实例的属性和方法,也可以通过它传递类的属性和方法,其名称self 并不是规定的名称,而是使用Python 编程时的惯用名称,该名称也可以自定义,例如使用this,但是最好还是按照惯例使用self。parameterlist 用于指定除self 参数以外的参数,各参数之间使用半角逗号“,”进行分隔。方法体的代码用于实现所需的功能。6.3.1 类的实例方法类的实例方法创建完成后,在类外部可以通过类的实例名称和点“.”操作符进行访问,其基本语法格式如下。instanceName.functionName( parameterValue )instanceName 表示类的实例名称;functionName 表示要调用的方法名称。parameterValue 表示调用方法时的实际参数,其个数与创建类的实例方法中parameterlist 的个数相同。6.3.1 类的实例方法【实例6-3】演示Python 类的实例方法的定义实例5-1 的代码如下所示。实例5-2 代码的运行结果如下。【说明】该运行结果为作者运行程序的输出结果,年份不同该结果有变化。6.3.1 类的实例方法从实例6-3 可以看出方法__calculateAge() 的名称由两个下划线开头,表明该方法为类的私有方法,只能在类的内部调用,不能在类的外部调用。在类内部调用实例方法的基本语法格式如下。self.__methodName()例如:self.__calculateAge()。在类外部可以调用类的公有方法,调用形式有以下两种。形式一:类实例名称. 实例方法名称( [ 参数值列表] )。例如:man.getAge()。通过实例名称man 调用getAge() 方法时,将实例对象man 自身作为第1 个参数传递给方法的参数self。形式二:类名称. 实例方法名称( 类实例名称 [, 参数值列表] )。例如:Person.getAge(man)。通过类名称Person 调用getAge() 方法时,也需要将实例对象man 自身作为参数传递给方法的参数self。6.3.2 类方法在Python 类的内部,使用def 关键字可以定义属于类的方法,这种方法需要使用@classmethod 来修饰,而且第1 个参数一般命名为cls(这只是Python 的惯用名称,也可以使用自定义名称,例如my)。类方法一般使用类的名称来调用,调用时会把类名称传递给类的第1 个参数cls,通过cls 来传递类的属性和方法,但不能传递实例的属性和方法。实例对象和类对象都可以调用类方法,调用类方法的基本语法格式如下。形式一:类实例名称. 类方法名称( [ 参数列表] )。形式二:类名称. 类方法名称( [ 参数列表] )。【注意】调用类方法与调用类的实例方法有所不同,使用类名称调用类方法时,并不需要将类实例名称作为参数显式传递给类方法。6.3.3 静态方法在Python 类的内部,还可以定义静态方法,这种静态方法需要使用@staticmethod 来修饰,静态方法没有self 和cls 参数,方法体中不能使用类或实例的任何属性和方法。实例对象和类对象都可以调用类的静态方法,要访问类的静态方法,可以采用类名称调用,并且不会向静态方法传递任何参数。调用类的静态方法的基本语法格式如下。形式一:类实例名称. 类静态方法名称()。形式二:类名称. 类静态方法名称()。静态方法是类中的函数,不需要实例。静态方法在逻辑上属于类,但是和类本身没有关系,也就是说静态方法中不会涉及类中的属性和方法的操作。可以理解为,静态方法是个独立的、单纯的函数,仅仅托管于某个类的名称空间中,便于使用和维护。定义商品类及其成员【任务6-1】【任务描述】(1)在PyCharm 中创建项目“Unit06”。(2)在项目“Unit06”中创建Python 程序文件“t6-1.py”。(3)定义商品类Commodity。(4)定义类的多个公有属性和私有属性。(5)定义多个实例方法。(6)分别通过类名称、实例名称访问类的属性。(7)分别通过类的实例方法输出类的公有属性和私有属性值。【任务6-1】01【任务实施】02成功启动PyCharm 后,在指定位置“D:\PycharmProject\”创建PyCharm 项目“Unit06”。在PyCharm 项目“Unit06”中,新建Python 程序文件“t6-1.py”,PyCharm 窗口中显示程序文件“t6-1.py”的代码编辑区域,在该程序文件的代码编辑区域中自动添加了模板内容。03在文件“t6-1.py”的代码编辑区域中的已有模板注释内容下面输入代码,程序文件“t6-1.py”中类定义的代码如下所示。【任务6-1】【任务实施】04针对创建的类Commodity 实施以下各项操作。(1)直接使用类名称访问类的公有属性。(2)使用类的实例名称访问类的公有属性(3)调用类的实例方法输出类的公有属性【任务6-1】【任务实施】04针对创建的类Commodity 实施以下各项操作。(4)通过类名称或类的实例名称访问类的私有属性(5)调用类的实例方法输出类的私有属性修改与访问类属性、创建实例属性【任务6-2】【任务描述】(1)在项目“Unit06”中创建Python 程序文件“t6-2.py”。(2)创建类Commodity 并定义其属性和方法。(3)创建类对象goods1 和goods2。(4)通过类名称Commodity 调用类的实例方法,输出类初始定义的公有属性。(5)使用类名称Commodity 修改类的公有属性。(6)直接使用类名称Commodity 输出类修改之后的公有属性。(7)使用类实例名称goods1 输出类修改之后的公有属性。(8)使用类实例名称goods2 输出类修改之后的公有属性。(9)通过类名称Commodity 调用类的实例方法,输出类修改之后的公有属性。(10)通过类实例名称goods1 调用类的实例方法,输出类修改之后的公有属性。(11)第2 次修改类的公有属性。(12)直接使用类名称Commodity 输出类第2 次修改之后的公有属性。(13)使用类实例名称goods1 输出类第2 次修改之后的公有属性。(14)使用类实例名称goods2 输出类第2 次修改之后的公有属性。(15)通过类名称Commodity 调用类的实例方法,输出类第2 次修改之后的公有属性。(16)分别通过类实例名称goods1、goods2 调用类的实例方法,输出类第2 次修改之后的公有属性。【任务6-2】01【任务实施】在PyCharm 项目“Unit06”中,新建Python 程序文件“t6-2.py”,在该程序文件“t6-2.py”的代码编辑区域中创建类Commodity 并定义其属性和方法的代码详见“t6-1.py”对应的代码。【任务6-2】02【任务实施】针对创建的类Commodity 进行类属性、实例属性的修改与访问。(1)创建类对象(2)通过类名称Commodity 调用类的实例方法,输出类初始定义的公有属性。(3)使用类名称Commodity 修改类的公有属性。【任务6-2】02【任务实施】针对创建的类Commodity 进行类属性、实例属性的修改与访问。(4)直接使用类名称Commodity 输出类修改之后的公有属性。(5)使用类实例名称goods1 输出类修改之后的公有属性。(6)使用类实例名称goods2 输出类修改之后的公有属性。【任务6-2】02【任务实施】针对创建的类Commodity 进行类属性、实例属性的修改与访问。(7)通过类名称Commodity 调用类的实例方法,输出类修改之后的公有属性。(8)通过类实例名称goods1 调用类的实例方法,输出类修改之后的公有属性。(9)第2 次修改类的公有属性。【任务6-2】02【任务实施】针对创建的类Commodity 进行类属性、实例属性的修改与访问。(10)直接使用类名称Commodity 输出类第2 次修改之后的公有属性。(11)使用类实例名称goods1 输出类第2 次修改之后的公有属性。(12)使用类实例名称goods2 输出类第2 次修改之后的公有属性。【任务6-2】02【任务实施】针对创建的类Commodity 进行类属性、实例属性的修改与访问。(13)通过类名称Commodity 调用类的实例方法,输出类第2 次修改之后的公有属性。(14)分别通过类实例名称goods1、goods2 调用类的实例方法,输出类第2 次修改之后的公有属性。运行结果之一 运行结果之二 运行结果之三定义与访问类的实例方法【任务6-3】【任务描述】(1)在项目“Unit06”中创建Python 程序文件“t6-3.py”。(2)在程序文件“t6-3.py”中创建类对象goods。(3)在程序文件“t6-3.py”中调用多个类的实例方法,输出所需数据。【任务6-3】01【任务实施】在PyCharm 项目“Unit06”中创建Python 程序文件“t6-3.py”。在程序文件“t6-3.py”中编写代码,实现所需功能。创建类Commodity 并定义私有属性、实例方法的代码如下所示。【任务6-3】02【任务实施】针对创建的类Commodity 实施以下各项操作。(1)创建类对象goods。(2)调用多个类的实例方法,输出所需数据。程序文件“t6-3.py”的运行结果如下所示。循序渐进知识要点6.1 创建类及其对象 6.1.2 创建类的实例 6.2 类属性与实例属性 6.3 类方法与实例方法 6.3.1 类的实例方法 6.3.2 类方法 6.3.3 静态方法6 【任务6-1】定义商品类及其成员 【任务6-2】修改与访问类属性、创建实例属性 【任务6-3】定义与访问类的实例方法6.4 类的构造方法与析构方法6.4.1 类的构造方法6.4.2 类的析构方法6.5 类的继承与方法重写6.5.1 类的继承6.5.2 方法继承6.5.3 方法重写6.6 Python 3的命名空间和作用域6.4.1 类的构造方法在Python 中,类有一个名为“__init__”的特殊方法,称为构造方法,该方法在类实例化时会自动调用,不需要显式调用。【说明】“__init__”是Python 默认的方法名称,其开头和结尾处是两个下划线(下划线中间没有空格)。在创建类时,类通常会自动创建一个__init__() 方法,每当创建一个新的类实例时,如果用户没有重新定义构造方法,则系统自动执行默认的构造方法__init__(),进行一些初始化操作。对于如下代码,实例化类Person 时,对应的__init__() 方法就会被调用。man = Person ()6.4.1 类的构造方法【实例6-4】演示Python 类的构造方法定义实例6-4 的代码如下所示。运行结果姓名: 李明性别: 男年龄: 196.4.2 类的析构方法在Python 中,析构方法的基本语法格式为:__del__(self)。在释放对象时系统自动调用该方法,不需要显式调用,可以在该方法中编写代码,进行一些释放资源的操作。循序渐进知识要点6.1 创建类及其对象 6.1.2 创建类的实例 6.2 类属性与实例属性 6.3 类方法与实例方法 6.3.1 类的实例方法 6.3.2 类方法 6.3.3 静态方法6 【任务6-1】定义商品类及其成员 【任务6-2】修改与访问类属性、创建实例属性 【任务6-3】定义与访问类的实例方法6.4 类的构造方法与析构方法6.4.1 类的构造方法6.4.2 类的析构方法6.5 类的继承与方法重写6.5.1 类的继承6.5.2 方法继承6.5.3 方法重写6.6 Python 3的命名空间和作用域6.5.1 类的继承1.单一继承Python 支持类的继承,子类的定义如下所示。class DerivedClassName( ParentClassName ):< 类体>其中,DerivedClassName 用于指定子类名称;ParentClassName 用于指定要继承的父类名称,可以有多个,对于单一继承只有一个。如果不指定父类名称,则继承Python 的基类object。类体为实现所需功能的代码,包括属性、方法的定义,如果定义类时暂时无须编写代码,可以直接使用pass 语句代替。父类ParentClassName 必须与子类定义在一个作用域内。6.5.1 类的继承【实例6-5】演示Python 类和单一继承子类的定义实例6-5 的代码如下所示。运行结果父类Person 的属性name 值为: 李明父类Person 的属性sex 值为: 男子类Student 的属性name 值为: 李明子类Student 的属性sex 值为: 男子类Student 的属性grade 值为: 956.5.1 类的继承2.多重继承Python 在一定程序上支持多继承形式。多继承的类定义基本语法格式如下。class DerivedClassName( ParentClassName1, ParentClassName2,… ):需要注意小括号中父类的顺序,若父类中有相同的方法名,而子类在使用时未指定继承自哪个父类,Python 将从左至右搜索括号中的父类。DerivedClassName 用于指定子类名称,ParentClassName1、ParentClassName2……则表示继承的多个父类名称,使用半角逗号“,”分隔。6.5.2 方法继承子类可以继承父类的实例方法,也可以增加自己的实例方法。子类对象可以直接调用父类的实例方法,调用的基本语法格式如下。子类名称. 父类方法名称( [ 参数列表] )例如member.printTest()。6.5.3 方法重写父类的成员都会被子类继承,如果程序中的父类方法的功能不能满足需求,可以在子类重写父类中的同名方法,子类可以覆盖父类中的任何方法,子类的方法中也可以调用父类中的同名方法。循序渐进知识要点6.1 创建类及其对象 6.1.2 创建类的实例 6.2 类属性与实例属性 6.3 类方法与实例方法 6.3.1 类的实例方法 6.3.2 类方法 6.3.3 静态方法6 【任务6-1】定义商品类及其成员 【任务6-2】修改与访问类属性、创建实例属性 【任务6-3】定义与访问类的实例方法6.4 类的构造方法与析构方法6.4.1 类的构造方法6.4.2 类的析构方法6.5 类的继承与方法重写6.5.1 类的继承6.5.2 方法继承6.5.3 方法重写6.6 Python 3的命名空间和作用域6.6 Python 3 的命名空间和作用域在理解Python 的命名空间和作用域前,先看一下计算机中的多个磁盘、多个文件夹与多个文件的存储关系。计算机中可以有多个硬盘,同一个硬盘中可以有多个逻辑分区(即磁盘),同一个磁盘中可以有多个文件夹,同一个文件夹中可以有多个文件。并且同一个磁盘中不能出现重名的文件夹,同一文件夹中不能出现重名的文件,但不同磁盘或不同文件夹中的文件可以重名。x01.txt02.txt02.txty01.txt文件夹x文件夹y磁盘E:文件夹x磁盘F:x01.txty01.txt6.6 Python 3 的命名空间和作用域Python 的命名空间提供了在项目中避免名称冲突的一种方法。各个命名空间是独立的,没有任何关系,所以虽然一个命名空间中不能有重名,但不同的命名空间是可以有重名的。Python 的命名空间结构主要由包、模块、类、函数、方法、属性、变量组成,相同的对象名称可以存在于多个命名空间中。一个Python 项目中可以定义多个包,并且包名要不同,例如“package01”“package02”;一个包中可创建多个模块,同一个包中的多个模块名称要不同,不同包的模块可以重名;一个模块中可以定义多个类、函数、变量,同一个包的同一个模块中定义的类、函数、变量的名称要不同,不同的包或同一个包的不同模块中定义的类、函数、变量可以重名;一个类中可以定义多个属性、方法,同一个类中的多个属性、方法名称要不同,不同名称的类或不同级别的类(父类与子类)中定义的属性、方法可以重名;一个函数中可以定义多个变量,同一个函数中的多个变量名称要不同,不同函数中定义的变量可以重名。6.6 Python 3 的命名空间和作用域Python 的命名空间结构如图所示。package01module01ClassAClassB methodXattributeMattributeNmethodXattributeMattributeN methodXattributeMattributeN functionXfunctionYmodule02variableMvariableNvariableMvariableNmodule01package02ClassA ClassB methodXattributeMattributeN methodXattributeMattributeN 项目N1.3 种命名空间(1)内置命名空间(Built-in Namespace)Python 内置的名称,例如函数名abs、char 和异常名称BaseException、Exception 等。(2)全局命名空间(Global Namespace)。全局名称指模块中定义的名称,记录了模块级变量,包括函数、类、其他导入的模块级的变量和常量。(3)局部命名空间(Local Namespace)局部名称指函数中定义的名称,记录了函数级变量,包括函数的参数和局部定义的变量。类内以及类的方法中定义的名称也属于局部名称。2.命名空间的查找顺序假设要使用变量var,则Python 的查找顺序为:局部命名空间→全局命名空间→内置命名空间。如果找不到变量var,它将放弃查找并引发NameError异常。运行结果如下。NameError: name 'var' is not defined3.命名空间的生命周期命名空间的生命周期取决于对象的作用域,如果对象执行完成,则相应命名空间的生命周期结束。因此,我们无法从外部命名空间访问内部命名空间的对象。示例如下。#var1 是全局名称var1 = 5def local_func():#var2 是局部名称var2 = 6def inner_func():# var3 是内置的局部名称var3 = 74.作用域在Python 中,程序的变量并不是在任何位置都可以访问的,访问权限取决于这个变量是在哪里赋值的。变量的作用域决定了哪一部分程序可以访问哪些特定的变量。Python 的作用域一共有4 种,具体如下。局部作用域(L,Local):最内层,包含局部变量,例如一个函数或方法内部。闭包函数外的函数(E,Enclosing):包含非局部(Non-Local)、非全局(Non-Global)的变量;例如两个嵌套函数,一个函数(或类)A 里面又包含一个函数B,那么对于B 中的名称来说A 的作用域就为Non-Local。全局作用域(G,Global):当前程序的最外层,例如当前模块的全局变量。内置作用域(B,Built-in):包含内置的变量、关键字等,最后才被搜索。4.作用域Python 查找的规则顺序为:L → E → G → B。即在局部作用域找不到,便会去局部作用域外的局部找(例如闭包函数外的函数),如果没找到就会去全局作用域查找,最后去内置作用域中查找。示例如下。g_count = 1 # 全局作用域def outer():o_count = 2 # 闭包函数外的函数中def inner():i_count = 3 # 局部作用域4.作用域内置作用域是通过一个名为builtins 的标准模块来实现的,但是这个变量名并没有放入内置作用域内,所以必须导入这个模块才能够使用它。在Python 3.0 中,可以使用以下的代码来查看builtins 模块中预定义了哪些变量。>>>import builtins>>>dir(builtins)在Python 中,只有模块、类以及函数才会引入新的作用域,其他的代码块(例如try…except、if…elif…else、for…while 等)是不会引入新的作用域的,也就是说这些语句内定义的变量,在其外部也可以访问,示例代码如下。>>>if True:msg = 'I wish you good health.'>>> msg'I wish you good health.'4.作用域以上代码中msg 变量定义在if 语句块中,但在其外部也可以访问msg 变量。如果将msg 定义在函数中,则它就是局部变量,在其外部不能访问,示例如下。>>>def printInfo():msg_inner = 'I wish you good health.'>>>msg_inner运行以上代码时会出现如下异常信息。Traceback (most recent call last):File "", line 1, in NameError: name 'msg_inner' is not defined从以上异常信息可以看出,msg_inner 未定义,无法使用,因为它是局部变量,只有在函数内可以使用。5.全局变量和局部变量定义在函数内部的变量拥有局部作用域,定义在函数外的变量拥有全局作用域。局部变量只能在其被定义的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内定义的变量名称都将被加入作用域中。【实例6-6】演示Python 的全局变量和局部变量的定义与使用实例6-6 的代码如下所示。函数内是局部变量: 26.0函数外是全局变量: 0运行结果6.关键字global 和nonlocal当在内部作用域想修改外部作用域的变量时,就要用到global 关键字。在函数内部,既可以使用global 关键字来声明使用外部全局变量,也可以使用global 关键字直接定义全局变量。【实例6-7】演示在函数内定义与修改全局变量num实例6-7 的代码如下所示。函数内部1 : 2函数内部2 : 5函数外部1 : 5函数外部2 : 8运行结果THANKS 展开更多...... 收起↑ 资源预览