第三章 过程大于结果

3.1 懒人炒菜机

1. 函数是什么

函数,英文Function,顾名思义函数就是一种功能,简写 f,将输入的东西变为另一种输出 。
比如,人本来是没穿衣服的,衣服可以让人改变气质,让人变得不一样。没穿衣服的人就是输入,衣服是Function,气质有所改变的人是输出,这里的 f 就衣服;再比如机器猫里面看到的缩小灯,人本来是正常大小,通过缩小灯,可以变成矮小的人。正常大小的人就是输入,缩小灯就是Function,矮小的人就是输出。

缩小灯就是Function

数学上的函数代表了集合之间的对应关系,如 f(x) = x2
而对于程序员来说,函数是一种语法结构,它将一些指令封装打包在一起,形成一个实现某种功能的工具。输入的数据叫做参数,输出的数据叫做返回值

2. 定义函数

Python中定义函数依靠关键字def,格式如下

def Function_Name(arg1,arg2,……):
    指令1(前面要有缩进)
    指令2(前面要有缩进)
    指令3(前面要有缩进)
    指令4(前面要有缩进)
          ……
     若有return语句,则程序只执行到return语句

如,唱生日歌,每一个人生日都要唱生日歌,那么人名就是作为输入,而输出就是唱生日为该人庆祝。

"""
无定义函数时
给小明,小红分别唱生日歌:
"""
print("Happy Birthday To You")
print("Happy Birthday To You")
print("Happy Birthday To You")
print("Happy Birthday To 小明")
print("Happy Birthday To You")

print("Happy Birthday To You")
print("Happy Birthday To You")
print("Happy Birthday To You")
print("Happy Birthday To 小红")
print("Happy Birthday To You")

"""
重复的歌词太多,我们可以定义函数装起来
"""
def Birthday_Song(name):
    print("Happy Birthday To You")
    print("Happy Birthday To You")
    print("Happy Birthday To You")
    print("Happy Birthday To " + name)
    print("Happy Birthday To You")

Birthday_Song("小明")
Birthday_Song("小红")

结果:
Happy Birthday To You
Happy Birthday To You
Happy Birthday To You
Happy Birthday To 小明
Happy Birthday To You
Happy Birthday To You
Happy Birthday To You
Happy Birthday To You
Happy Birthday To 小红
Happy Birthday To You
----------------分割线:只执行到return语句--------------------
def Birthday_Song(name):
    print("Happy Birthday To You")
    print("Happy Birthday To You")
    print("Happy Birthday To You")
    print("Happy Birthday To " + name)
    return print(name+" 生日快乐!")  """只执行到return语句"""
    print("Happy Birthday To You")

Birthday_Song("小明")
结果:
Happy Birthday To You
Happy Birthday To You
Happy Birthday To You
Happy Birthday To 小明
小明 生日快乐!

3. 调用函数

就是使用那个函数的名字,然后若是有参数,则输入参数。

print()  """print()也是一个函数"""
print("这是参数")
结果:

这是参数

4.函数文档

有时候如果对一个函数不知道它是用来干什么的,我们可以查看它的函数文档。

方法1:使用help()函数查看函数文档。如查看print函数,记得要去掉括号
用help()函数查看print函数

方法2:使用 "?" 查看。记得去括号。
用 "?" 查看

3.2 参数传递

1. 基本传参

  • 形式参数:进入函数所需要的参数。
  • 实际参数:实际进入函数的数据。
    形参与实参
    传参:实际参数通过形式参数,传入到函数中。
    基本传参
    1)通过位置传参、2)通过关键字传参、3)位置与关键字混用传参
"""打印参数函数"""
def Print_args(a,b,c):
    print(a,b,c)

"""1)通过位置传参"""
Print_args(1,2,3)
结果:1 2 3

"""2)通过关键字传参"""
Print_args(c=3,b=2,a=1)
结果:1 2 3

"""3)位置与关键字混用传参"""
Print_args(1,c=2,b=3)  结果:1 3 2
Print_args(a=1,b=2,3) """报错"""
Print_args(3,b=2,a=1) """报错"""

"""由此可见,尽量传参尽量不要混合使用,一般使用位置传参。"""

2. 包裹传参

若函数需要多个参数时,我们可以使用包裹传参。格式如下

"""参数以元组的形式装入:包裹位置传参"""
def function1(*args):   """ * 表示多个参数需要输入"""
    语句……

"""参数以字典的形式装入:包裹关键字传参"""
def function2(**args):   """ ** 表示多个关键字和参数需要输入"""
    语句……

1)包裹位置传参、2)包裹关键字传参、3)两者混用

"""举例"""
 """1)包裹位置传参"""   
def Package_args_pos(*args):
    print(args)

Package_args_pos(1,3,4,5)
Package_args_pos(2,6,7,9,10,11)
结果:
(1, 3, 4, 5)
(2, 6, 7, 9, 10)
两次调用的参数不一样,但是由于包裹传参,依旧可以进行,
将这些参数按照顺序收入到一个元组中,输出的是一个包含参数的元组。

 """2)包裹关键字传参"""  
def Package_args_keyw(**args):
    print(args)
    
Package_args_keyw(a=1,b=3) """关键字是a,b;值是1,3"""
Package_args_keyw(x=2,y=6,z=7) """关键字是x,y,z;值是2,6,7"""

结果:
{'a': 1, 'b': 3}
{'x': 2, 'y': 6, 'z': 7}
由于有关键字的存在,因此以字典的形式将参数装入,
形成一个个键值对,最终以字典的形式输出。

 """3)包裹关键字传参"""  
def Package_args_mix(*args1,**args2):
    print(args1)
    print(args2)

Package_args_mix(1,3,5,a=2,b=4,c=4)
Package_args_mix(2,4,6,a=1,b=3,c=5)
结果:
(1, 3, 5)
{'a': 2, 'b': 4, 'c': 4}
(2, 4, 6)
{'a': 1, 'b': 3, 'c': 5}

3. 解包裹(unpacking)

将一个容器(元组、列表、字典)里面的各参数分解出来。

"""解元组"""
  方式(1)
Tuple = (1,3,4,5)
print(*Tuple)
结果:1 3 4 5

  方式(2)
def Unpacking(a,b,c):
  print(a,b,c)

Tuple = (1,3,4)
Unpacking(*Tuple)
结果:1 3 4

"""解列表"""
  方式(1)
List = [2,4,5,6]
print(*List)
结果:2 4 5 6

  方式(2)
def Unpacking(a,b,c):
  print(a,b,c)

List = [2,4,5,6]
Unpacking(*List)
结果:2 4 5

"""不能直接这样解字典"""
Dict = {"a":1,"b":2,"c":3}
print(**Dict)
会报错

  方式(2)
def Unpacking(a,b,c):
  print(a,b,c)

Dict = {"x":1,"y":2,"z":3}
Unpacking(**Dict)  """有两个*号"""
结果:1 2 3

"""
无论是元组、字典、列表方式(2)解包裹,只有参数个数与容器元素个数一样时才可以使用。
"""

3.3 递归

1.高斯求和

递归的两种方式
我们一般情况下讨论的递归指函数对本身的调用。
递归会一直调用本身,所以我们需要一个递归出口使其结束。
我们可以想象递归相当于"俄罗斯套娃",不断重复着同样的娃娃,而递归出口就是当娃娃最小时,就不再继续重新返回,将套娃装好。
俄罗斯套娃

下面举一个高斯求和的例子来说明。
现在要求1到100的和,除了循环外,我们还可以使用递归。

"""定一个求和函数"""
def gauss_Sum(n):  """n指的是从1加到n"""
      if  n == 1:   """递归出口,当加的数为1的时候,就重新套回去"""
            return 1;
      else:
            return n + gauss_Sum(n - 1)  """不然就是n + (n-1)"""

print(gauss_Sum(100))
结果:5050

2.函数栈(Stack)

栈是一种数据结构,栈中的元素叫,帧按照"先进后出"的规则进出栈。
1)压栈(push)
当有新的元素进入栈时,用push把元素压入栈,而旧的元素也会被挤到下方。

push

2)弹栈(pop)

当有元素出栈时,用pop把元素弹出栈,剩余元素也会被弹起,但不会弹出栈。
pop

先进后出
push and pop

3.变量的作用域

1)局部变量
函数内部定义的变量。不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响。局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储。
2)全局变量
定义在.py模块(相当于主程序main())内部,作用在整个.py模块。生命周期:从变量被创造开始到.py模块结束死亡。

A = 100 """ 全局变量 """
def fun():
    a = 10 """ 局部变量 """
    return a + 100
print(A)  """ 可以正常输出全局变量的值"""
 """ print(a) 出现错误: name 'a' is not defined 
试图在函数体外获取一个局部变量的值不行"""

结果:100
num = 0

def Demo1():
    num = 1
    print("在demo1中的结果:",num)

def Demo2():

    print("在demo2中的结果:",num)

Demo1()
Demo2()

print("在函数外面中的结果:",num)

结果:
在demo1中的结果: 1
在demo2中的结果: 0
在函数外面中的结果: 0
分析:
从结果可以看出,我们在demo1中num = 1,只在demo1内部起作用,而全局变量num仍然是0;
因为在python中,在函数内部改变全局变量的值,会默认的在函数内部创建一个新的变量,
全局变量并没有改变。要想要改变全局变量的值,需要在函数内部用global声明。
-------------分割线------------------
num = 0

def Demo1():
    global num
    num = 1
    print("在demo1中的结果:",num)

def Demo2():

    print("在demo2中的结果:",num)

Demo1()
Demo2()

print("在函数外面中的结果:",num)
""'
运行结果为:
在demo1中的结果: 1
在demo2中的结果: 1
在函数外面中的结果: 1
"""

3.4 引入那把宝剑

1.引入模块

导入第三方模块的三种方式
1)import 函数库名

"""导入乌龟画图库"""
import turtle

2)import 函数库名 as 简称

"""导入乌龟画图库"""
import turtle as t

3)from 函数库名 import 函数

"""导入乌龟画图库里的所有函数"""
from turtle import *
"""导入乌龟画图库里的某个函数"""
from turtle import fillcolor

3.5 异常处理

1.bug

bug意为虫子,也指程序中出现的错误
1)语法错误:这种错误通常编译器会帮你找出。

for i in range(10)
        print(i)
将不执行代码,因为for()后面没有加冒号:

for i in range(10):
print(i)
将不执行代码,因为没有缩进

a = [1,2,3]
print(a[3])
错误,下标越界错误。

2)语义错误:这种错误比较隐蔽,不易发现。

想要获得一个后面有小数点的数字,但是会发现输出的是整数。
def average(x, y):
     return x + y / 2
print(average(1,2)) 
预期结果:1.5
实际结果:2.0
因为Python自动将其认为是整型的,故自动向上取整。

3)异常

1 / 0
Traceback (most recent call last):
  File "<input>", line 1, in <module>  # 异常信息所在位置
ZeroDivisionError: division by zero  # 异常类型及引起原因

2.Debug

写完代码后,对代码进行调试、排除错误异常的过程。

3.异常处理

对于比较可能出现错误的代码,可以在这些代码之前做一些处理。这样既可以使得程序结束前进行更多的操作,如获取关于错误的信息,帮助Debug;还可以让程序在犯错后依旧走下去
异常处理的语句如下:

try:
     ……
except exception1 as e1 :
     ……
except exception2 as e2:
     ……若语句错误则捕获异常
else:
     ……没有异常发生时执行else子句。
finally:
     ……不管有没有异常发生最终都执行finally子句。

以上是自动抛出异常,对于无法自动抛出的异常。我们可以手动抛出。使用关键字raise

raise Exception

举例

try:
    x = int(input("输入整数:"))
    y = int(input("输入整数:"))
    if y == 0:
        raise Exception("主动抛出ZeroDivisionError")
    print(x / y)
except NameError as e:
    print("Error:",e)
except ValueError as e:
    print("Error:",e)
else:
    print("没有异常发生时执行")
finally:
    print("有无异常发生均执行")
    
结果1:
输入整数:10
输入整数:0
有无异常发生均执行
Traceback (most recent call last):
Exception: 主动抛出ZeroDivisionError

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

推荐阅读更多精彩内容

  • 3.1 懒人炒菜机 3.1.1 函数是什么 集合的对应关系 数据转换的魔法盒子 语句的封装。输入数据被称为参数,参...
    SibyLtuI阅读 345评论 0 0
  • 3.1 懒人炒菜机 1.何为函数 函数(Function)在数学上的定义是指集合之间的对应关系。从数据的角度,函数...
    尘濯阅读 716评论 0 3
  • 一 函数 1.1函数是什么 ①集合的对应关系 ②数据的“魔法盒子” ③语句的封装 1.2.1定义函数 制作函数的过...
    大饼与我阅读 182评论 0 1
  • 3.1懒人炒菜机 1.函数 三种看待函数的方式:集合的对应关系、数据的魔法盒子(数据转换)、语句的封装 2.定义函...
    lammmya阅读 245评论 0 0
  • 每一次迎来新的一年,我都会在心里祈祷,真希望这辈子所有糟糕的事在过去的岁月里都发生完了。 一直都想着写一篇关于老幺...
    羥羊阅读 221评论 0 2