Python从基础到进阶——「模块&面向对象编程」(1)模块和类

模块:用来组织代码

  • 概念/目的:为了避免再次进入python解释器时重新定义(函数和变量),并将过长的程序进行拆分管理,或者便于在不同的程序中使用同一个便捷的函数,因此把定义放在一个文件里,并在脚本或解释器的交互式实例中使用它们(模块)。

  • 本质:模块是一个包含Python定义和语句的文件。文件名就是模块名后跟文件后缀 .py在这里插入图片描述

探索模块

在这里插入图片描述

模块的结构布局

在这里插入图片描述

包:用来组织模块

在这里插入图片描述

类:用来组合数据和功能

类(Class)和实例(Instance)是面向对象最重要的两个概念。

类是抽象的模板,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。

类的概念

类提供了一种组合数据和功能的方法。 创建一个新类意味着创建一个新的对象 类型,从而允许创建一个该类型的新 实例 。 每个类的实例可以拥有保存自己状态的属性。 一个类的实例也可以有改变自己状态的(定义在类中的)方法。
在这里插入图片描述

创建类和实例

在这里插入图片描述

类的操作

类对象支持两种操作:属性引用实例化

  • 属性引用 使用 Python 中所有属性引用所使用的标准语法: obj.name。
class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

MyClass.i 和 MyClass.f 就是有效的属性引用,将分别返回一个整数和一个函数对象。
doc 也是一个有效的属性,将返回所属类的文档字符串: “A simple example class”。

  • 类的实例化 使用函数表示法。 可以把类对象视为是返回该类的一个新实例的不带参数的函数。举例来说(假设使用上述的类):
x = MyClass()

创建类的新 实例 并将此对象分配给局部变量 x。

  • 实例对象
    实例对象理解的唯一操作是属性引用

    有两种有效的属性名称,数据属性方法

补充

作用域、命名空间和 LEGB 原则

作用域 = 命名空间

在这里插入图片描述
在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过_前缀来实现的。

  • 正常的函数和变量名是公开的(public),可以被直接引用,比如:abc,x123,
  • 类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途 -> 用于类和子类
  • 类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用 -> 仅仅用于类自己(子类也不能引用)

具体地说,在代码中变量名被赋值(Python 中变量声明即赋值,global 声明的只是变量的使用域)的位置决定了该变量能被访问的范围。函数定义了本地作用域,而模块定义的是全局作用域。这两个作用域之前有如下关系:

  • 每一个模块都是全局作用域。也就是说,创建于模块文件顶层的变量具有全局作用域,对于外部访问就成了一个模块对象的属性。

  • 全局作用域的作用范围仅限于单个文件。“全局”指的是在一个文件的顶层变量名对于这个文件而言是全局的。

  • 每次对函数的调用都创建了一个新的本地作用域。Python 中也有递归,即可以调用自身,每次调用都会创建五个新的本地命名空间。

  • 赋值的变量名除非声明为全局变量,否则均为本地变量。如果需要在函数内部对模块文件顶层的变量名赋值,需要在函数内部通过 global 语句声明该变量。

  • 所有的变量可归纳为本地、全局或者内置三种。范围分别为 def 内部,在一个模块的命名空间内部和预定义的 builtin 模块提供的变量。

命名空间 = 作用域

在 Python 程序中创建、改变或查找变量名时,都是在一个保存变量名的地方进行中,那个地方我们称之为命名空间。作用域这个术语也称之为命名空间

白话一点讲:命名空间是对变量名的分组划分。 不同组的相同名称的变量视为两个独立的变量,因此隶属于不同分组(即命名空间)的变量名可以重复。
命名空间可以存在多个,使用命名空间,表示在该命名空间中查找当前名称。

在这里插入图片描述
在这里插入图片描述

LEGB 原则

LEGB含义解释:
L-Local(function);函数内的名字空间
E-Enclosing function locals;外部嵌套函数的名字空间(例如closure)
G-Global(module);函数定义所在模块(文件)的名字空间
B-Builtin(Python);Python内置模块的名字空间

前面讲到,Python的命名空间是一个字典,字典内保存了变量名称与对象之间的映射关系,因此,查找变量名就是在命名空间字典中查找键-值对
Python有多个命名空间,因此,需要有规则来规定,按照怎样的顺序来查找命名空间,LEGB就是用来规定命名空间查找顺序的规则

LEGB规定了查找一个名称的顺序为:local–>enclosing function locals–>global–>builtin

另解:

在函数命名空间中:

  • 变量名引用分为三个作用域进行查找:首先是本地,然后是函数内(如果有的话),之后是全局,最后是内置。
  • 在默认情况下,变量名赋值会创建或者改变本地变量。
  • 全局声明将会给映射到模块文件内部的作用域的变量名赋值。

Python 的变量名解析机制也称为 LEGB 法则,具体如下:

当在函数中使用未确定的变量名时,Python 搜索 4 个作用域:本地作用域(L),之后是上一层嵌套结构中 def 或 lambda 的本地作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按这个查找原则,在第一处找到的地方停止。如果没有找到,Python 会报错的。

标准文件模板

在这里插入图片描述

运行测试

在这里插入图片描述

举例

Python本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用。

我们以内建的sys模块为例,编写一个hello的模块:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

' a test module '

__author__ = 'Michael Liao'

import sys

def test():
    args = sys.argv
    if len(args)==1:
        print('Hello, world!')
    elif len(args)==2:
        print('Hello, %s!' % args[1])
    else:
        print('Too many arguments!')

if __name__=='__main__':
    test()

第1行和第2行是标准注释,第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身使用标准UTF-8编码;

第4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;

第6行使用__author__变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名;

以上就是Python模块的标准文件模板,当然也可以全部删掉不写,但是,按标准办事肯定没错。

后面开始就是真正的代码部分。

注意到这两行代码:

if __name__=='__main__':
    test()

当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试

更多细节可以参考 廖雪峰-使用模块

参考:

Python LEGB规则

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值