第五章:函数和代码复用

A、函数的基本使用


1.函数的定义

函数是一段具有特定功能的、可重用的语句组,用函数名来表示,并通过函数名进行功能调用。

函数也可以看作是一段具有名字的子程序,可以在需要的地方调用执行,不需要在每个执行地方重复编写这些语句。

每次使用函数可以提供不同的参数作为输入,以实现对不同数据的处理。

函数执行后,还可以反馈相应的处理结果。

函数是一种功能抽象(类似黑盒)。

    使用函数的目的

    降低编程难度

    代码重用


函数的使用:

函数定义

Python安装包自带的函数:

    Python内置函数(abs()、eval()、input())

    Python标准库中的函数(math.sqrt())

自定义函数(用户自己编写)

函数调用


自定义函数

Python定义一个函数使用def保留字:

自定义函数


函数定义时,所指定的参数是一种占位符

函数定义后,如果不经过调用,不会被执行

函数定义时,参数是输入,函数体是处理,结果是输出(IPO)

函数名:任何有效的Python标识符

参数列表:调用函数时给它的值

        参数个数>=0

        多个参数用 , 分隔

形式参数(形参):定义函数时使用,只在函数内部有用。

实际参数(实参):调用函数时使用。可以是常量、变量、表达式、函数。

函数体:函数被调用时执行的代码

return语句

    结束函数调用,并将结果返回给调用者

    可选

    可以出现在函数体的任意位置

    如果没有return语句,函数在函数体结束位置将控制权返回给调用方

函数接口:返回值和参数

函数传递信息的途径

    通过函数返回值的方式传递信息

    通过参数传递信息

实例:生日歌

过生日时要为朋友唱生日歌,歌词为:

Happy birthday to you!

Happy birthday to you!

Happy birthday, dear <名字>

Happy birthday to you!

要求:编写程序为Mike和Lily输出生日歌。

最简单的实现方法是重复使用print()语句

生日歌

2.函数调用的过程

程序调用一个函数需要执行以下四个步骤:

(1)调用程序在调用处暂停执行;

(2)在调用时,将实参复制给函数的形参;

(3)执行函数体语句;

(4)函数调用结束给出返回值(return),程序回到调用前的暂停处继续执行。


3.lambda函数

Python有33个保留字,其中一个是lambda,用于定义一种特殊的函数 — 匿名函数,又称lambda函数

匿名函数并非没有名字,而是将函数名作为函数结果返回,如下:

<函数名> =

lambda <参数列表>: <表达式>

lambda函数与正常函数一样,等价于下面形式:

def <函数名>(<参数列表>):

    return <表达式>

简单说,lambda函数用于定义简单的、能够在一行内表示的函数,返回一个函数类型。

举例

谨慎使用lambda函数

lambda函数主要用作一些特定函数或方法的参数

lambda函数有一些固定的使用方式,建议逐步掌握

一般情况下,建议使用def定义普通函数


B、函数的参数传递


1.函数的参数

    函数的形参、实参。

    函数可以定义可选参数,使用参数的位置或者名称传递参数值。

    根据函数中变量的不同作用域有不同的函数返回值方式。


2.可选参数和可变数量参数

在定义函数时,有些参数可以存在默认值

参数可以存在默认值

在函数定义时,可以设计可变数量参数

    通过参数前增加星号(*)实现

    必须放在参数列表的最后

    调用时,这些参数被当做元组类型传递到函数

举例

3. 参数的位置和名称传递

    函数调用时,默认将实参按照位置顺序传递给函数

    例如:func(x1,y1,z1,x2,y2,z2)

                     return

   实际调用:result=func(1,2,3,4,5,6)

    可读性差

    提供了按照形参名称输入实参的方式,调用如下

    result=func(x2=4, y2=5, z2=6, x1=1, y1=2,z1=3)

由于调用函数时指定了参数名称,所以参数之间的顺序可以任意调整


4. 函数的返回值

    return语句用来退出函数,并将程序返回到函数被调用的位置继续执行。

    return语句同时可以将0个、1个或多个函数运算完的结果返回给函数被调用处的变量,例如:

返回值

函数可以没有return,此时函数并不返回值,等价于return none。

没有return
举例

用return返回多个值,也可以根据多返回值的顺序进行赋值。

return返回多个值  
举例

返回值可以是一个变量,也可以是一个表达式

表达式

5. 函数对变量的作用

函数通过参数与调用程序传递信息。

函数的形参值接收了实参的值,给形参赋值不影响实参。

Python通过值来传递参数

一个程序中的变量包括两类:

局部变量指在函数内部使用的变量,仅在函数内部有效,当函数退出时变量将不存在。

全局变量指在函数之外定义的变量,一般没有缩进,在程序执行全过程有效。

全局变量

原因:当函数执行完退出后,其内部变量将被释放。

如果函数内部使用了全局变量呢?

局部变量

函数func()内部使用了变量n,并且将变量参数b赋值给变量n,为何全局变量n值没有改变

如果希望让func()函数将n当作全局变量,需要在变量n使用前显式声明该变量为全局变量

全局变量

如果全局变量不是整数n,而是列表类型ls,会怎么样呢?

列表类型ls

如果func()函数内部存在一个真实创建过且名称为ls的列表,则func()将操作该列表而不会修改全局变量。

ls的列表是否改变

Python函数对变量的作用遵守如下原则:

        简单数据类型变量无论是否与全局变量重名,仅在函数内部创建和使用,函数退出后变量被释放;

        简单数据类型变量在用global保留字声明后,作为全局变量;

        对于组合数据类型的全局变量,如果在函数内部没有被真实创建的同名变量,则函数内部可直接使用并修改全局变量的值;

        如果函数内部真实创建了组合数据类型变量,无论是否有同名全局变量,函数仅对局部变量进行操作。


C、datetime库的使用


引入模块

from datetime import datetime

1.datetime库概述

以不同格式显示日期和时间是程序中最常用到的功能。

Python提供了一个处理时间的标准函数库datetime,它提供了一系列由简单到复杂的时间处理方法。datetime库可以从系统中获得时间,并以用户选择的格式输出。

datetime库亿格林威治时间为基础。

每天划分为3600×24秒。

两个常量:datetime.MINYEAR(=1) 和datetime.MAXYEAR (=9999)。

datetime库以类的方式提供多种日期和时间表达方式

datetime.date:日期表示类,表示年、月、日等

datetime.time:时间表示类,表示小时、分钟、秒、毫秒等

datetime.datetime:日期和时间表示的类,功能覆盖date和time类

datetime.timedelta:时间间隔有关的类

datetime.tzinfo:与时区有关的信息表示类


2.datetime库解析

使用datetime.now()获得当前日期和时间对象

作用:返回一个datetime类型,表示当前的日期和时间,精确到微秒。

例子

使用datetime.utcnow()获得当前日期和时间对应的UTC(世界标准时间)时间对象,使用方法如下:

datetime.utcnow()

作用:返回datetime类型,表示当前日期和时间的UTC表示,精确到微秒。

例子

datetime.now()和datetime.utcnow()都返回一个datetime类型的对象,也可以直接使用datetime()构造一个日期和时间对象,使用方法如下:

datetime(year, month, day, hour=0,

minute=0,second=0, microsecond=0)

作用:返回一个datetime类型,表示指定的日期和时间,可以精确到微秒。

调用datetime()函数直接创建一个datetime对象,表示2018年4月16日22:33,32秒7微秒,执行结果如下:

例子

程序已经有了一个datetime对象,进一步可以利用这个对象的属性显示时间,为了区别datetime库名,采用上例中的someday代替生成的datetime对象

方法

datetime对象有3个常用的时间格式化方法,如表所示:

方法

isoformat()和isoweekday()方法的使用如下:

举例

strftime()方法是时间格式化最有效的方法,几乎可以以任何通用格式输出时间

方法

strftime()格式化字符串的数字左侧会自动补零,上述格式也可以与print()的格式化函数一起使用

举例


D、七段数码管绘制


1.七段数码管绘制

七段数码管(seven-segment indicator)由7段数码管拼接而成,每段有亮或不亮两种情况,改进型的七段数码管还包括一个小数点位置。

七段数码管

七段数码管能形成27=128种不同状态,其中部分状态能够显示易于人们理解的数字或字母含义,因此被广泛使用。下图给出了十六进制中16个字符的七段数码管表示。

16个字符的七段数码管表示

要求:

用程序绘制七段数码管。

用程序绘制七段数码管

基本思路:

绘制单个数字对应的数码管

获得一串数字,绘制对应的数码管

获得当前系统时间,绘制对应的数码管


每个0到9的数字都有相同的七段数码管样式,因此,可以通过设计函数复用数字的绘制过程

进一步,每个七段数码管包括7个数码管样式,除了数码管位置不同外,绘制风格一致,也可以通过函数复用单个数码段的绘制过程

步骤1:绘制单个数字对应的数码管

七段数码管有7个基本线条组成

七段数码管可以有固定顺序

不同数字显示不同的线条

 

E、代码的复用和模块化设计


1.代码的复用

把代码当做资源进行抽象

代码资源化:程序代码是一种用来表达计算的“资源”。

代码抽象化:使用函数等方法对代码赋予更高级别的定义。

代码复用:同一份代码在需要的时候可以被重复使用 –– 首先要对代码进行抽象

函数 对象 是代码复用的两种主要形式

函数:将代码命名在代码层面建立了初步的抽象。

对象:属性和方法

<a>.<b>和.()

在函数之上再次组织进行抽象

函数是程序的一种基本抽象方式,它将一系列代码组织起来通过命名供其他程序使用。

函数封装的直接好处是代码复用,任何其他代码只要输入参数即可调用函数,从而避免相同功能代码在被调用处重复编写。

代码复用产生了另一个好处,当更新函数功能时,所有被调用处的功能都被更新(更新便利)。

当程序的长度在百行以上,如果不划分模块,就算是最好的程序员也很难理解程序含义,程序的可读性就已经很糟糕了。

最好解决方法:将一个程序分割成短小的程序段,每一段程序完成一个小的功能

无论面向过程和面向对象编程,对程序合理划分功能模块并基于模块设计程序是一种常用方法,被称为“模块化设计”。

2. 模块化设计

模块化设计的核心:分而治之

通过函数或者对象封装,将程序划分为模块和模块之间的表达

具体包括:主程序、子程序和子程序间关系

子程序:模块

主程序:模块间的关系

分而治之:一种分而治之、分层抽象、体系化的设计思想

模块化设计一般有两个基本要求

紧耦合:两个部分的交流很多,无法独立存在。

松耦合:两个部分的交流较少,有清晰简单的接口,可以独立存在。

一般来说,完成特定功能或被经常复用的一组语句应该采用函数来封装,并尽可能减少函数间参数和返回值的数量,这样复用的可能性越高。

尽可能合理划分功能块,功能块内部耦合紧密--紧耦合

模块间关系尽可能简单,功能块之间耦合度低--松耦合


F、函数的递归


递归的定义

函数作为一种代码封装,可以被其他程序调用,当然,也可以被函数内部代码调用。这种函数定义中调用函数自身的方式称为递归。就像一个人站在装满镜子的房间中,看到的影像就是递归的结果。

递归在数学和计算机应用上非常强大,能够非常简洁的解决重要问题。

递归

递归不是循环

阶乘的例子揭示了递归的两个关键特征

 (1)存在一个或多个基例,基例不需要再次递归,它是确定的表达式;

 (2)计算出存在的递归链,所有递归链要以一个或多个基例结尾。

类似数学归纳法

 (1)证明当n 取第一个值的时候,命题成立

 (2)假设当nk 时命题成立,证明当n=nk+1时命题也成立

 (3)递归是数学归纳法思维在编程中的体现


递归的使用方法

实例:阶乘的计算。

举例

分析

利用函数+分支语句实现上述代码。

递归本身是一个函数,需要以函数定义方式描述

函数内部,采用分支语句对输入参数进行判断

基例和递归链,分别编写对应的代码。     

 

注意:

构造递归函数,需要基例

基例不进行递归,否则递归就会无限循环执行

此递归调用以字符串形式执行,应设置基例为空串


F、科赫曲线绘制


科赫曲线

高大上的分形几何

分形几何是一种迭代的几何图形,广泛存在于自然界中。(整体与局部有很强的相似性。)

科赫(Koch)曲线

在众多经典数学曲线中非常著名,由瑞典数学家冯·科赫(H·V·Koch)于1904年提出,由于其形状类似雪花,也被称为雪花曲线。

科赫曲线的基本概念和绘制方法如下:

正整数n代表科赫曲线的阶数,表示生成科赫曲线过程的操作次数。

科赫曲线初始化阶数为0,表示一个长度为L的直线。

对于直线L,将其等分为三段,中间一段用边长为L/3的等边三角形的两个边替代,得到1阶科赫曲线,它包含四条线段。

进一步对每条线段重复同样的操作后得到2阶科赫曲线。继续重复同样的操作n次可以得到n阶科赫曲线

科赫曲线

科赫曲线属于分形几何分支,它的绘制过程体现了递归思想。

        递归思想:函数+分支

        递归链条:线段的组合

        递归基例:初始线段

代码
结果

雪花效果:科赫曲线的组合

代码
结果


G、Python内置函数


Python解释器提供了68个内置函数,其中,前36个已经将结果,需要掌握。

内置函数


H、PyInstaller库基本介绍


需求:将python源代码(.py)转化为无需源代码的可执行文件。即:以可执行文件的方式执行一段程序,从而可以在未安装python IDLE和解释器的电脑上运行。

需要将源程序编译或者打包成一个直接可以执行的程序。

过程

PyInstaller是第三方库

官方网站:

       http://http://www.pyinstaller.org/

第三方库:使用前需要额外安装

安装第三方库需要使用pip工具(使用cmd)

使用cmd命令行

       pip

install pyinstaller

安装需要连接互联网

安装pyInstaller库后,会生成一个pyInstaller程序(命令),用于将源文件打包,生成可执行文件。

使用命令行(cmd),因为pyinstaller是命令行的执行程序,而不是python下面的执行指令。

       pyinstaller–F <文件名.py>

举例
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,302评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,563评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,433评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,628评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,467评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,354评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,777评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,419评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,725评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,768评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,543评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,387评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,794评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,032评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,305评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,741评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,946评论 2 336

推荐阅读更多精彩内容

  • 〇、前言 本文共108张图,流量党请慎重! 历时1个半月,我把自己学习Python基础知识的框架详细梳理了一遍。 ...
    Raxxie阅读 18,897评论 17 410
  • 第五章 函数和代码复用 函数的基本使用 函数的定义 函数是一段具有特定功能的、可重用的语句组,用函数名来表示并通过...
    jplee阅读 4,144评论 0 1
  • 黄昏 太阳把最后的光 温柔的送给这半球上的所有需要 又要去关照另一拨儿 清醒了的人们 一些吃饱饭的人 在有花有...
    云淡风轻之蓝阅读 511评论 18 21
  • 我一定是错过了什么对吗? 是在书上,还是在本子上,还是其它的? 可是我已经全都丢了,属于初中的回忆,全被我丢掉了。...
    相与__阅读 1,032评论 0 0