第五讲:函数与类库

第五讲:函数与类库

第五讲:函数与类库

函数

定义

函数就是代码块,只不过我们给这个代码块特地进行命名,固定住它以后就

用来干某个具体的工作。

当我们需要用程序多次执行同一项任务时,就会需要反复编写完成该任务的代码,这将会使我们的代码变得冗长繁杂,所以函数诞生了。我们只需要把这个需要反复编写的代码块定义为某个函数并命名,使用的时候只需要调用它的名字,即可反复执行任务。所以函数的优点是能够通过代码复用是的程序本身的编写、阅读、测试、修复和改进更加简易。

函数定义格式:

python 复制代码
def text(id):
    a = id + "真厉害!"
    return print(a)

text("xqs")
text("123")
text("1234")

函数名为 text,参数为 id,函数作用为输出简单的称呼,函数体为 S = id + "真厉害!" ,返回值为 print(a) 。函数调用为text("xqs") text("123")。

实参与形参

函数text(id)要求给id指定一个值。当我们调用这个函数并给定值的时候,它就会输出感恩话语。

其实,在函数text(id)的定义中,变量id是一个形参------形式上的参数,即函数执行任务所需的一项信息。在函数调用text("xqs")的时候,我们向形参传递了一个实参------实际参数,即函数执行任务所拥有的一项信息------"xqs",此时实参"xqs"被储存在形参id中。同理,函数调用text("123")时,实参"123"被储存在形参id中;函数调用text("1234")时,实参"1234"被储存在形参id中。

实参

由于函数定义中可能会含有多个形参,因此函数调用中也需要输入多个实参。向形参传递实参的方式主要有两种:位置实参和关键字实参。

  1. 位置参数
    在调用参数函数时,必须将每个形参都赋值为每个实参。最简单的关联方式是基于形参的位置顺序传递实参,这种关联方是成为位置参数。
python 复制代码
def thank_you(something, name):
    R = "You help me with " + something + "." + name
    S = "Thank you," + name
    return print(R,S)

thank_you("Chinese","xqs")
thank_you("123","456")

这个函数定义为thank_you(something, name),形参顺序是something,name,正确的顺序是先"Chinese"后"xqs"。正确的实参传递是,第一个是You help me with Chinese . xqs;第二个是You help me with xqs . Chinese;

  1. 关键字参数
    由于形参顺序太难处理,我们就可以使用关键字参数方法。关键字参数方法是传递给函数一对------"形参名称-实参",直接将形参和实参关联起来,因此不会出现顺序混淆导致的错误结果,并且能够指出函数调用各个值的意义。
python 复制代码
def thank_you(something, name):
    R = "You help me with " + something + "." + name
    S = "Thank you," + name
    return print(R,S)

thank_you(something="Chinese",name="xqs")
thank_you(name="xqs",something="Chinese")

当我们指定了将 something 赋值为"Chinese",将 name 赋值为"xqs"之后,不论顺序如何,都能够正确地输出结果。

变量的作用域

根据程序中变量所在的位置和作用域,分为局部变量和全局变量。

  1. 局部变量
    局部变量是指在函数内部定义的变量,仅在函数内部有效。
python 复制代码
def thank_you(something, name):
    R = "You help me with " + something + "." + name
    S = "Thank you," + name
    return print(R,S)

thank_you(something="Chinese",name="xqs")
thank_you(name="xqs",something="Chinese")
print(R)

我们在函数外部使用函数内部变量 R 的时候,会提示 R 没有定义,即不存在。

  1. 全局变量
    全局变量是指在函数外部定义的变量,在整个程序中有效。若要在函数内部使用全局变量,则分为两种情况:一是单纯引用,则不需要任何操作;二是需要在函数内部修改全局变量,则需要提前使用保留字 global 声明。

返回值

函数没有返回值,因此打印输出的结果为 None

函数加上了 return 返回了立方值,因此打印输出结果为 8。

代码复用

  1. 简单的代码复用
    编写函数称为封装,执行函数称为调用,代码复用即将封装起来的函数进行调用。
python 复制代码
def text(x):
    a = x**3
    print(a)

def thank_you(something, name):
    R = "You help me with " + something + "." + name
    S = "Thank you," + name
    return print(R,S)

text(2)
thank_you(something="2的立方值",name="xqs")

text(5)
thank_you(name="xqs",something="5的立方值")

先封装两个函数,然后分别进行调用。

  1. 将函数储存在模块
    将函数储存在模块中,再将模块导入主程序。通过将函数储存在独立文件中,可以把重点放在程序的更高层逻辑上。还能帮助我们在其他程序编写中使用此函数,还可以将此函数分享给其他程序员,同样地还可以使用其他程序员编写的函数库。

首先创建模块,模块是扩展名为.py 的文件,其中为封装好的函数。xqs.py 即为模块我们创建的摸块。

(1) 导入整个模块

当我们导入整个模块之后,那么模块包含的函数就可以使用了。

在同一个文件夹下创建了一个求立方和表示感谢的 py 文件,在这个文件中导入刚才创建的模块,再进行函数调用,可以发现这些代码运行正确。这种导入整个模块再进行函数调用的方法总结为:

(2) 导入指定函数

如果整个模块有许多函数,而我们只需要其中的一、两个函数,那么我们可以指定函数名进行特定导入。这种导入指定函数的方法总结为:

(3) 使用 as 给模块指定别名

我们的模块名为"xqs",稍显冗长。我们可以给他指定一个缩写名,方便使用,可以得到一样的运行结果。这种以别名导入模块的方法总结为:

(4) 使用 as 给函数指定别名

我们的函数名为"thank_you",稍显冗长。我们可以给他指定一个缩写名,方便使用。

(5) 导入模块中的所有函数

使用(*)符号可以导入模块中的所有函数,如果模块不是自己写的,由于函数名很可能会重复,所以出现一些意想不到的结果。导入模块中的所有函数的方法总结为:

综上,代码复用最为推荐以上的第(3)种方式------使用 as 给模块指定别名,这样会减少出错概率,并且使代码更为清晰、更加容易阅读和理解。

类就是对象的抽象式汇总,基于类创建对象的时候,每个对象都具有类的通用属性,在获得通用属性的基础上,可根据需要赋予对象以个性。

创建和使用类

  1. 创建类

现在创建一个表示猫咪的简单类 Cat(习惯上类的命名一般都是开头字母大写)。想象一下猫咪,能联想到的共性是两条信息(名字、胖瘦)和两种动作(舔毛、踩奶),所以我们创建的 Cat 类将包含他们。

Cat类的语法结构:

具体解释:

第 1 行,类的命名应为首字母大写,括号内是空的;

第 2 行,我们对这个类的功能进行了说明;

第 4 行,我们开始在类中编写函数,实际上除了上文中的模块,类是函数的另一种汇总方式,在类中的函数我们称为方法。

显然在这个类中有三种方法,首先是第 4 行的__ini__()方法,然后是第 9 行的舔毛()方法,再是第 13 行的踩奶()方法。其中__ini__()方法是类中特有的默认的方法,每当我们根据 Cat 类创建新实例时,Python 都会自动运行它。注意它的开头末尾各有两个下划线,这是默认约定,能够避免与我们定义的普通函数发生命名冲突。

单独对__ini__()方法进行剖析,在此方法中包含了三个形参:self、name 和身材。首先,形参 self 不可缺失且必须位于参数最前。具体原因不必深究,这么做的目的是可以理解为方便自己引用自己。再之,对于形参 self,我们不需要传递实参。最后,对于后面两个形参,每次创建 Cat 类实例时,都需要给他俩提供实参。

对于另外两个方法:舔毛()和踩奶()。由于这些方法是单独定义的,因此不需要额外的信息,因此只需要一个形参 self。在这里,舔毛()和踩奶()只是打印一条信息说明猫咪是在作出行为,但是随着学习我们可以编写一个动画真正实现。

python 复制代码
class Cat():
    def __init__(self, name, 身材):
        self.name = name
        self.身材 = 身材

    def 舔毛(self):
        print(self.name + "正在舔毛")

    def 踩奶(self):
        print(self.name + "正在踩奶")
  1. 实例化

接下来将 Cat 类实例化,即创建一个表示特定猫咪的实例,它的名字叫咪咪,身材属性是胖。

python 复制代码
class Cat():
    def __init__(self, name, 身材):
        self.name = name
        self.身材 = 身材

    def 舔毛(self):
        print(self.name + "正在舔毛")

    def 踩奶(self):
        print(self.name + "正在踩奶")

my_cat = Cat("咪咪","胖")

(1)访问属性

self.name 和 self.身材是 Cat 类中的属性,舔毛()和踩奶()是 Cat类中的方法。访问属性时采用句点表示法:

python 复制代码
class Cat():
    def __init__(self, name, 身材):
        self.name = name
        self.身材 = 身材

    def 舔毛(self):
        print(self.name + "正在舔毛")

    def 踩奶(self):
        print(self.name + "正在踩奶")

my_cat = Cat("咪咪","胖")

print("My cat's name is " + my_cat.name + ".")
print("我的小猫咪身材" + my_cat.身材 + "。")

(2)调用方法

调用方法时,也采用句点表示法:

python 复制代码
class Cat():
    def __init__(self, name, 身材):
        self.name = name
        self.身材 = 身材

    def 舔毛(self):
        print(self.name + "正在舔毛")

    def 踩奶(self):
        print(self.name + "正在踩奶")

my_cat = Cat("咪咪","胖")

my_cat.舔毛()
my_cat.踩奶()

(3)创建多个实例

我们可根据需求创建其他的实例,比如你也有一只猫,那我也可以把你的猫实例化。

python 复制代码
class Cat():
    def __init__(self, name, 身材):
        self.name = name
        self.身材 = 身材

    def 舔毛(self):
        print(self.name + "正在舔毛")

    def 踩奶(self):
        print(self.name + "正在踩奶")

my_cat = Cat("咪咪","胖")
print("My cat's name is" + my_cat.name + ".")
print("我的小猫咪身材" + my_cat.身材 + "。")
my_cat.踩奶()

your_cat = Cat("喵喵","瘦")
print("My cat's name is" + my_cat.name + ".")
print("我的小猫咪身材" + my_cat.身材 + "。")
your_cat.舔毛()

继承

  1. 继承父类

如果要编写的类是另一个已经编号的类的特殊版本,那么就可以使用继承。类 a 继承另一个类 A 的时候,将自动获得类 A 的所有属性和方法;原有的类 A 成为父类,新类 a 成为子类。子类除了继承其父类的所有属性和方法之外,还可以定义自己的属性和方法。
例如,模拟英短猫这个品种的猫咪,我们可以在前面创建的 Cat 类基础上创建新类 EdCat,只需要为英短猫特有的属性和行为编写代码。具体来说,EdCat 子类的创建首要完成任务是获得父类 Cat 类的属性,因此需要如下结构形式:首先是 Cat 类代码。创建子类时,父类必须包含在当前文件中,且位于子类前面。接着开始定义子类 EdCat(),括号中必须包含父类名。__init__方法中接受创建 Cat 实例所需信息,super()是一个能够将父类和子类关联的特殊函数,完成继承。

为了测试继承是否成功,创建了my_edcat英短猫my_edcat并输出其身材,发现其与猫咪信息相同,具备猫咪的属性,所以继承成功。

python 复制代码
class Cat():
    def __init__(self, name, 身材):
        self.name = name
        self.身材 = 身材

    def 舔毛(self):
        print(self.name + "正在舔毛")

    def 踩奶(self):
        print(self.name + "正在踩奶")

class EdCat(Cat):
    def __init__ (self,name,身材):
        super().__init__(name,身材)

my_edcat = EdCat("咪咪","胖")
print(my_edcat.身材)
  1. 子类定义新属性和方法

子类继承了父类属性之后,可添加一些子类特有的新属性和方法。

以英短猫为例,添加新属性以及一个相关联的方法。新属性为英短猫特点以及描述特点的方法。

python 复制代码
class Cat():
    def __init__(self, name, 身材):
        self.name = name
        self.身材 = 身材

    def 舔毛(self):
        print(self.name + "正在舔毛")

    def 踩奶(self):
        print(self.name + "正在踩奶")

class EdCat(Cat):
    def __init__ (self,name,身材):
        super().__init__(name,身材)
        self.英短特点 = "圆脸尖耳,好奇心强,与人亲近"

    def 描述_英短特点(self):
        print("英短猫的特点是:" + self.英短特点 + "。")

my_edcat = EdCat("咪咪","胖")
my_edcat.描述_英短特点()

代码注释:

第 15 行是新属性,第 17 行是与新属性相关联的新方法,第 21 行是调用新方法,运行结果说明新属性和新方法定义成功。如果有需要还可以添加其他新属性与方法,来更加清晰地定义英短猫的类,Python 并无限制。

  1. 重写父类方法

某些父类方法可能不符合子类的特性,我们可以对其进行重写。只要在子类中定义一个与父类重名的方法,Python 在运行时将不会考虑父类方法,而直接选择子类定义的相应方法作为运行对象。

比如 Cat()类中有一个踩奶()的方法,对于英短来说,没有瘦的,都是胖圆健硕的,所以要重写方法。

python 复制代码
class Cat():
    def __init__(self, name, 身材):
        self.name = name
        self.身材 = 身材

    def 舔毛(self):
        print(self.name + "正在舔毛")

    def 踩奶(self):
        print(self.name + "正在踩奶")

class EdCat(Cat):
    def __init__ (self,name,身材):
        super().__init__(name,身材)
        self.英短特点 = "圆脸尖耳,好奇心强,与人亲近"

    def 描述_英短特点(self):
        print("英短猫的特点是:" + self.英短特点 + "。")

    def 踩奶(self):
        print(self.name + "英短踩奶")

my_edcat = EdCat("咪咪","胖")
my_edcat.踩奶()

导入类

为了让代码尽可能实现这个理念,python 允许将类存储在模块中,在主程序中导入所需模块简化代码。上一小节讲了函数可以存储在模块中简化代码,这一节将讲述将类存储在模块中简化代码。

  1. 导入单个类
    (1) 创建包含单个类的模块

首先创建一个只包含 Cat()类的模块,代码与之前的 Cat()类完全相同,区别只是我们将其存储在 cat.py 的模块中。

(2) 导入单个类

紧接着我们导入 Cat()类并将其实例化,用 from <模块名> import <类名> 语句打开模块 cat 并导入其中的 Cat()类。

PS:如果这个 my_cat.py 文件中包含了整个 Cat 类,它的长度像之前所展示的,非常之长。但是通过将类转移到模块中,编写代码时,导入该模块,就可以使用其所有功能,主程序代码将会整洁易读。从代码编写过程中的逻辑思维来讲,底层逻辑将会被储存在模块这种独立文件中,我们就能够专注于更高层的逻辑。

python 复制代码
import cat
my_cat = cat.Cat("咪咪","胖胖")
my_cat.踩奶()
print("\n")
my_edcat = cat.EdCat("哈哈","健硕")
my_edcat.踩奶()
  1. 导入多个类
    (1) 创建包含多个类的模块

首先创建一个包含 Cat()类和 EdCat()类的模块,既可以模拟猫,也可以模拟英短猫。代码与之前的 Cat()类和 EdCat()类完全相同,区别只是我们将其存储在cat.py 的模块中。

(2) 导入多个类

我们要在同一个程序中创建猫咪和英短猫咪,因此我们同事导入 Cat()和EdCat()两个类,导入相应的类之后,就可以根据需要创建任意数量的实例,在这个示例中,我们创建了一只叫咪咪的小猫咪和一只叫哈哈的英短猫咪。

python 复制代码
from cat import Cat, EdCat

my_cat= Cat("咪咪","胖胖")
print("My cat's name is " + my_cat.name + ".")
print("我的小猫咪身村" + my_cat.身材 + "的。")
my_cat.踩奶()

print("\n")

my_edcat = EdCat("哈哈","健硕")
print("我的英短的名字是" + my_edcat.name + "。")
my_edcat.踩奶()
my_edcat.描述_英短特点()
  1. 导入整个模块
    (1)导入整个模块

导入整个模块之后,使用句点表示法访问需要的类。

python 复制代码
import cat
my_cat = cat.Cat("咪咪","胖胖")
my_cat.踩奶()
print("\n")
my_edcat = cat.EdCat("哈哈","健硕")
my_edcat.踩奶()

(2)导入模块中的所有类

与之前的导入模块中的所有函数相同,使用语法为:

这种方式不推荐,因此不列举具体示例。

不推荐的原因有两点:一是不能清除地知道程序使用了哪些类,二是有可能会出现相同命名的名称。

模块与库

概念

  1. 模块
    模块即一组函数或者一组类,它的作用是将函数或者类成组地保存为独立文件,方便我们更专注于程序编写的更高层逻辑。

  2. 库即一组模块,它的作用是将模块成组地保存为独立文件,方便我们更专注于程序编写的更更高层逻辑。

前面 4 讲所学的普通程序语句是最底层,后面的函数和类算是平级(但是类中可以包含多个方法,类中方法即函数),类稍大一级,都归于中层,再后面的模块是高层,最后是超高层------库。

标准库

库分为标准库和第三方库,标准库是 Python 内置的,无需安装;第三方库则是由国内外大神自己开发的开源使用的库,需要安装。

  1. turtle 库
    turtle(海龟)是一个能够进行图形绘制的库,它的绘制概念非常直观------turtle 小海龟在笛卡尔直角坐标系中爬行,其爬行轨迹形成了图形。小海龟最初位于坐标系原点(0, 0),前进方向为 X 轴正向,小海龟有有"前进"、"旋转"、"后退"等爬行操作,如,输入以下代码,"小海龟"正在向前爬 1000个像素。
python 复制代码
import turtle
turtle.forward(1000)

下面介绍一道 Python 二级真题,让我们来看看具体如何考察?

考生文件夹下存在一个文件 PY201.py,请写代码替换横线,不修改其他代码,实现以下功能:【10 分】

使用turtle库的turt1e.right()函数和turt1e.fd()函数绘制一个正方形,

边长为 200 像素,效果如图所示。

python 复制代码
import turtle

#方法一
d = 0
for i in range(4):
    turtle.fd(200)
    d += 90
    turtle.seth(d)

#方法二
for i in range(1,5):
    turtle.fd(200)
    turtle.seth(90*i)

#方法三
for i in range(4):
    turtle.fd(200)
    turtle.seth(90)

turtle.fd()是前进函数,turtle.seth()函数可以改变海龟的行进方向(角度按逆时针)。方法二是一个 for 循环,不做过多解释;方法三中turtle.left()函数也可以改变海龟的行进方向(角度按逆时针)。

  1. random 库
    Python 提供的 random 库可用于产生各种分布的伪随机数序列。在random 库中,最基本的函数random.random(),它能够胜出一个[0.0, 1.0)之间的随机小数。

    下面是一道 Python 二级真题,让我们来看看具体如何考察?
    考生文件夹下存在一个文件 PY103.py,请写代码替换横线,不修改其他代码,题目要求如图 5.36,实现以下功能:【5 分】
  • 以 123 为随机数种子,随机生成 10 个在 1(含)到 999(含)之间的随机数,每个随机数后跟随一个逗号进行分隔,屏幕输出这 10 个随机数
  • random.seed()是产生随机数种子的函数,random.randint()函数可以在某个数字范围内产生随机数,end 参数可以在每个输出结果后面进行逗号分隔。

第三方库

从 Python 实用性角度来讲,随着我们对 Python 的理解更深、应用更广,肯定会安装各种各样的第三方库,这些库都是大神免费开发并提供给我们使用的宝贵财富。比如我们在处理 Excel 表格时,会用到 openpyxl 库、xlsxwriter 库、数据处理库 numpy 和 pandas、包括画图库 matplotlib;在开发网站时,会用到 Django库;在编写爬虫时,会用到 Scrapy 库、requests 库、re 库;在科学数据处理时,会用到 scipy 库等等。

  1. 下载并安装(pip)
    如同 Python 编程之前需要安装 Python 编译器一样,使用第三方库之前首先要进行第三方库的下载与安装。在此仅提供一种最为简便、实用、好用的方法,即 pip 安装,使用方法是使用 win+R 键或者在开始菜单右键打开运行对话框,输入 cmd,打开命令提示符,然后输入一行命令:

    以安装 numpy 库为例
  2. 更换服务器

(1)临时性地更换服务器

这个方法操作非常简便,适用于新手和下载库较少的学习者。在原来 pip install <库名>的基础上加上这么一行:

(2)永久更换服务器

以清华大学服务器为例,介绍如何永久更换,也比较简单,是个一劳永逸的办法,也是三部曲:

(a)进入自己的系统用户名文件夹

(b)创建 pip 文件夹

(c)创建 pip.ini 文件并进行编辑如下内容:


  1. jieba 库

jieba("结巴")库是用于中文文本处理、对文本词语分割的库。

各个领域第三方库的名称进行了解

相关推荐
在下不上天7 分钟前
Flume日志采集系统的部署,实现flume负载均衡,flume故障恢复
大数据·开发语言·python
SEVEN-YEARS11 分钟前
深入理解TensorFlow中的形状处理函数
人工智能·python·tensorflow
EterNity_TiMe_15 分钟前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip
tatasix15 分钟前
MySQL UPDATE语句执行链路解析
数据库·mysql
Suyuoa27 分钟前
附录2-pytorch yolov5目标检测
python·深度学习·yolo
南城花随雪。28 分钟前
硬盘(HDD)与固态硬盘(SSD)详细解读
数据库
儿时可乖了29 分钟前
使用 Java 操作 SQLite 数据库
java·数据库·sqlite
ruleslol31 分钟前
java基础概念37:正则表达式2-爬虫
java