python第五章——函数

  • 第五章——函数
    • 5.1函数概述
    • 5.2 函数进阶
    • 下面部分之后再写
    • 5.3函数习题(一些小例子)

第五章——函数

5.1函数概述

快速入门:

#定义函数
def func():
print('123')#调用函数
func()

加小括号是调用函数,不加小括号可能是进行值的传递

(1)函数定义:实现某一项特定功能的代码块
(2)函数分类:内置VS自定义

1)内置函数:Python解释器已经写好的函数,无需对象访问,直接调用即可

2)自定义函数:
定义方式:def关键字
调用方式:就是直接写函数名()
注意:函数只有被调用的时候,才会执行里面的代码块

3)函数参数:
形参:形式上的参数,你传递的是啥,我就是啥
实参:实际传过去的参数

def func(a,b): # a,b就是形参
print(a+b)func('hello','world')        # 拼接(实参)
func(100,566)        # 运算(实参)#helloworld
#666

注意:形参和实参要一一对应

4)函数返回值:
关键字:return
说明:所有函数都有返回值,函数是去执行一项功能,执行完必然有反馈
作用:将结果返回给调用处,并结束当前代码
总结:学习一个函数,首先要知道它的功能,其次就是要知道它的参数和返回值

Structure里显示定义的函数

两种加法器实现方式:

# 加法器1
def fun1(a,b):
print(a+b)
# 加法器2
def fun2(a,b):
return a+b    # 更灵活fun1(10,20)
sum = fun2(30,40)
print(sum)

python这么写会报错:

fun()    # 调用动作必须在声明函数之后
def fun():
print('hello')

从函数中返回函数:
其实并不需要在一个函数里去执行另一个函数,我们也可以将其作为输出返回出来:

def greeting(name="hello"):def hello():return "now you are in the hello() function"def world():return "now you are in the world() function"if name == "hello":return helloelse:return worlda = greeting()
print(a)    # <function greeting.<locals>.hello at 0x0000018EE2AD7268>
print(a())  # now you are in the hello() function
b= greeting(name="world")
print(b())  # now you are in the world() function
print(greeting()()) # now you are in the hello() function

注:加小括号是调用函数,不加小括号是进行值的传递,为了在函数中执行另一个函数,在 if/else 语句中我们返回 hello 和 world,而不是 hello() 和 world()
将函数作为参数传给另一个函数:

def world():return "world!"def hello(func):print(func())hello(world)    # world!

练习题:
(1)定义一个函数,传递整数n,返回1-n之间的偶数和
(2)定义一个函数,使其能够将信息(数字密码)转成暗语输出

def fun1(n):
# 1.验证
import re
if not re.match(r'^-?\d+$',n):
return '非法输入'
# 2.求和
n = int(n)        # 负数不会报错
# 3.负数(这里将负数正常处理了,实际上负数是不能这样做的)
step = 1 if n>=0 else -1
sum=0
for i in range(1,n+step,step):
if i%2==0:
sum+=i
return sumnum = input('请输入一个整数:')
print(fun1(num))

(2)定义一个函数,使其能够将信息(数字密码)转成暗语输出
暗语规则:19004546 -> IPOOYSYG

两种实现方式:

def fun2(sr):
dt = {'0':'O','1':'I','2':'Z','3':'E','4':'Y','5':'S','6':'G','7':'L','8':'B','9':'P'}
ans = ''
for i in sr:
ans += dt[i]
return ansprint(fun2("123456789"))
def filter(pwd):        # 123
res = str(pwd)
if not res.isdecimal():
return '非法输入'
p = 'OIZEYSGLBP'
con = ''
for i in res:                # 传进来的每一个数就是p的索引值
con += p[int(i)]
return conpwd = input('请输入您的密码:')
print(filter(pwd))

5.2 函数进阶

1.pass空语句(用在测试):

# pass可以写在所有的冒号场景
# if/while/for/def/……
def fun1():
pass

2.关键字参数:

# 可以给形参和实参都设置关键字
def fun2(a='hello',b='world'):        # 形参关键字
print(a+b)
fun2()                # helloworld
fun2('123')                # 123world
fun2('123','456')                # 123456
# 实参关键字
fun2(a='python')                # pythonworld
fun2(b='java')                # hellojava
fun2(b='css',a='html')        # htmlcss 关键字参数可以不按顺序

3.可变参数:可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个

# 1)元组写法:
def fun3(*hobby):
print(hobby)
print('我的爱好是:')
for i in hobby:
print(i)
fun3('吃饭','睡觉','打游戏')'''
('吃饭', '睡觉', '打游戏')
我的爱好是:
吃饭
睡觉
打游戏
'''# 2)字典写法:
def fun4(**kwargs):    # 两个星号表示空字典
print(kwargs)# 关键字参数传值
fun4(id=10,user='root',pwd='123456')        # 键不加引号 {'id': 10, 'user': 'root', 'pwd': '123456'}
# 直接传字典本身,必须加**
fun4(**{'a':10,'b':20})    # {'a': 10, 'b': 20}

关键字参数与可变参数的综合应用:

def fun5(a,b=10,*res):
print(a,b,res)
fun5('hello')                # hello 10()
fun5('hello',123)                # hello 123()
fun5('hello',123,456,789)                # hello 123 (456, 789)
# a是普通参数放最左边,b是关键字参数,*res是可变参数(元组)必须放最后# 接收任意参数(顺序)
def fun6(*args,**kwargs):
print(args)
print(kwargs)fun6()                # {}
'''
()
{}
'''
fun6(a='hello')
'''
()
{'a': 'hello'}
'''
fun6(1,2,3,4,5)
'''
(1, 2, 3, 4, 5)
{}'''
fun6(1,2,3,b='xxx')                # 注意顺序
'''
(1, 2, 3)
{'b': 'xxx'}
'''

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple
而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict

4.作用域:
局部:函数内部
全局:函数外部

# 写法(1)
a = 10      # 全局
def fun():a = 20      # 局部
fun()
print(a)    # 10# 写法(2)
b = 10
def fun2():# 结论:当局部变量在当前作用域找不到的时候,向上寻找# 注意:只能向上寻找,不能向下寻找print(b)
fun2()      # 10# 写法(3)
# 需求:在函数内部修改全局变量
c = 10
def fun3():global  c       #注意:一定要先声明c = 20
fun3()
print(c)        # 20d = None      # 相当于java或c中的声明变量且没赋值
def fun4():global dd = 10
fun4()
print(d)        # 10# 写法(4)
def fun5(pwd):      # pwd形参(局部变量)print(pwd)
pwd = '123456'
fun5(pwd)       # 123456 pwd实参(全局变量)

推荐看一下其他人的文章以熟悉一下global()函数的其他用法

5.匿名函数:lambda表达式
说明:匿名就是函数没有名字

# 正常写法:
def fun(x,y):return x+y
print(fun(1,3))# 匿名写法
sum = lambda x,y:x+y

lambda表达式就是匿名函数,没有名称的函数,但返回的变量可以看成lambda的名称.正常调用函数的写法就是调用该变量的写法
说明:lambda只是一个表达式,不能单独存储,且函数体比直接def定义的函数要简单
说明:lambda主体是一个表达式,而不是一个代码块,所以在lambda表达式中封装的逻辑很有限

关于sort()排序:

(1)reverse场景

ls=[1,45,6,2,33,78,11]
ls.sort(reverse=True)
print(ls)   # [78, 45, 33, 11, 6, 2, 1]
ls.sort(reverse=False)
print(ls)   # [1, 2, 6, 11, 33, 45, 78]

(2)key的场景

def fun(con):return int(re.search('\d+',con).group())    # 每一句开头的数字 group()用来提出分组截获的字符串,()用来分组import resr = "12.一代天骄成吉思汗,只识弯弓射大雕。9.须晴日,看红装素裹,分外妖娆。2.千里冰封,5.惟余莽莽;3.万里雪飘,4.望长城内外,6.大河上下,1.北国风光,7.顿失滔滔。8.山舞银蛇,原驰蜡象,欲与天公试比高。11.惜秦皇汉武,略输文采;唐宗宋祖,稍逊风骚。13.俱往矣,数风流人物,还看今朝。10.江山如此多娇,引无数英雄竞折腰。"
ls = re.findall(r'\d+\D+',sr)
ls.sort(key=fun)        # 注意:key是函数,不能写括号,写括号是调用
for i in ls:i = re.findall(r'[\u4e00-\u9fa5]\D+', i)  # 去掉序号i = (' '.join(i))  # 去掉元组的括号print(i)

(3)lambda表达式

import resr = "12.一代天骄成吉思汗,只识弯弓射大雕。9.须晴日,看红装素裹,分外妖娆。2.千里冰封,5.惟余莽莽;3.万里雪飘,4.望长城内外,6.大河上下,1.北国风光,7.顿失滔滔。8.山舞银蛇,原驰蜡象,欲与天公试比高。11.惜秦皇汉武,略输文采;唐宗宋祖,稍逊风骚。13.俱往矣,数风流人物,还看今朝。10.江山如此多娇,引无数英雄竞折腰。"
ls = re.findall(r'\d+\D+',sr)
ls.sort(key=lambda con:int(re.search('\d+',con).group()))for i in ls:i=re.findall(r'[\u4e00-\u9fa5]\D+',i)   # 去掉序号i=(' '.join(i)) # 去掉元组的括号print(i)

lambda练习题:制作键为1-20的字典,值为50-100之间的随机分数
1)将字典随机打乱顺序(返回新字典){19:59,2:87,13:66,…}
2)按分数倒序构建新的字典{5:99,14:98,13:90,…}

from random import randint
from random import shuffledef dt_shuffle(dt):ls = list(dt.keys())shuffle(ls)return {key:dt[key] for key in ls}def dt_sorted(dt):# 思路:lambda表达式
# 思路:列表
#    ls = []
# 1)for循环:[(1,'aa'),(2,'bb'),(3,'cc')]
#    for key,value in dt.items():
#        ls.append((key,value))
# 2)以上思路用一个zip函数即可实现:[(1,'aa'),(2,'bb'),(3,'cc')]ls = list(zip(dt.keys(),dt.values()))ls.sort(reverse=True,key=lambda tp:tp[1])
# 新字典dt_new = {}dt_new.update(ls)return dt_newif __name__ == '__main__':# 1.制作字典dt = {x:randint(50,100) for x in range(1,21)}# 2.随机打乱# sorted() 内置函数 sorted(ls,key=lambda i:randint(0,9999))# shuffle() 随机数模块的方法dt = dt_shuffle(dt) # 随机打乱print(dt)# 3.值的排序dt = dt_sorted(dt)print(dt)

6.冒号与箭头:Python3.5新功能
说明:参数中的冒号指参数的类型建议符,告诉开发人员希望传入的实参类型(不是强制,类型不符也不报错)
说明:函数后面的箭头指函数的返回值建议符,用来说明函数返回值

def func(x:int,y:int) -> int:   # -> int表示建议返回值的类型是intsum = x+yreturn sumres1 = func('hello','world')
res2 = func(123,456)
print(res1)     # helloworld
print(res2)     # 579
print(res1,res2)    # helloworld 579

7.编程中的经典错误:列表引用问题

def fun(a,b):a+=breturn a
# 1
x=1
y=2
print(fun(x,y))     # 3
print(x)        # 1
print(y)        # 2# 2
x=(1,2)
y=(3,4)
print(fun(x,y))     # (1, 2, 3, 4)
print(x)        # (1, 2)
print(y)        # (3, 4)# 3
x=[1,2]
y=[3,4]
print(fun(x,y))     # [1, 2, 3, 4]
print(x)        # [1, 2, 3, 4] 变了,因为列表可变
print(y)        # [3, 4]# 结论:列表是引用传递(指针)在编程中应当注意此种问题,避免得到错误的列表
# 字典
def fun(dt):dt['id']='hello'return dtdt = {'user':'root'}
print(fun(dt))      # {'user': 'root', 'id': 'hello'}
print(dt)       # {'user': 'root', 'id': 'hello'}#列表
def func(ls):ls.append('hello')return dtdt={'user':'root'}
print(fun(dt))  # {'user': 'root', 'id': 'hello'}
print(dt)   # {'user': 'root', 'id': 'hello'}# 列表
def func(ls):ls.append('hello')return lsls = [1,2,3]
print(func(ls)) # [1, 2, 3, 'hello']
print(ls)   # [1, 2, 3, 'hello']

8.函数递归:递归就是自己调用自己
注意:递归的效率很低,只是有些场景下,递归写法很简单,代码可读性很高
注意:递归相当于死循环,必须有停止的点

# 嵌套调用(不是递归)
def fun1():fun2()
def fun2():fun3()
def fun3():print('hello')
fun1()      # hello# 递归
import time
def func(i):print('world')i += 1time.sleep(0.5)if i<=3:func(i)
func(0)'''
world
world
world
world
'''

9.函数闭包
语法:函数的闭包,通俗地讲,就是函数内部再写一个函数
作用:可以保持程序上一次运行后的状态,然后继续执行

# 正常传参
def fun(res):print(res)# 闭包传参
def func():num = 1def add(n):nonlocal num        # nonlocal只能在内嵌函数中使用,使用前提是外部函数必须先声明nonlocal声明的变量# nonlocal作用:内外共享一个变量num += nreturn numreturn add      # 返回的是内嵌函数的名字# 调用
f = func()
print(f(1))     # 2
print(f(2))     # 4 把上一行注释掉再运行一遍的话,就输出3
print(f(3))     # 7 把上一行注释掉再运行一遍的话,就输出4

注意:闭包必须满足一下3个条件,才会产生闭包
1)必须是函数嵌套
2)内部函数必须引用外部函数里的变量
3)外部函数必须返回内嵌函数

10.函数装饰器:

函数装饰器这里仅仅简单的介绍。详细了解可以看看作者“攻城狮白玉”的文章,写的非常透彻

说明:装饰器就是用于拓展原来函数功能的一种函数
实质:装饰器的本质就是闭包函数
场景:在不改变原函数名的情况下,给被装饰对象添加新的功能
原则:函数装饰器有开放封闭原则,即开放是对扩展进行开放,封闭是对修改封闭
1)不改变被装饰对象的源代码(因为容易影响之前的功能)
2)不改变被装饰对象的调用方式(因为调用处多的时候很麻烦)

需求:想要给func升级:获取计算时间

def func():sum = 0for i in range(101):sum+=iprint(sum)
func()

需求实现1:改变源码

import time
def func():start = time.time()sum = 0for i in range(101):sum += itime.sleep(0.01)print(sum)end = time.time()print(end-start)
func()

需求实现2:改变调用方式

import time
def func():sum = 0for i in range(101):time.sleep(0.01)        sum += iprint(sum)
def fn():start = time.time()func()end = time.time()print(end-start)fn()

需求实现3:闭包写法(避免违背开闭原则)

import time
def func():sum = 0for i in range(101):time.sleep(0.01)sum += iprint(sum)def timer(fn):      # fn就是函数名def test():start = time.time()fn()        # 调用end = time.time()print(end-start)return testa=timer(func)
a()

需求实现4:装饰器写法

import time
# 装饰器构建
def timer(fn):      # fn就是函数名def test():start = time.time()fn()        # 调用end = time.time()print(end-start)return test
# 装饰器写法
@timer      # 注解
def func():sum = 0for i in range(101):time.sleep(0.01)sum+=iprint(sum)
# 调用
func()

多个装饰器

# 装饰器1
def fn01(func):def inner():print('fn01')func()print('fn01')return innerdef fn02(func):def inner():print('fn02')func()print('fn02')return innerdef fn03(func):def inner():print('fn03')func()print('fn03')return inner@fn03
@fn02
@fn01
def func():print('hello123')# 调用
func()
# 输出结果:
#fn03
#fn02
#fn01
#hello123
#fn01
#fn02
#fn03

下面部分之后再写

装饰器习题:
(1)为一个列表推导式函数增加一个验证纯数字的功能
(2)星座问题


5.3函数习题(一些小例子)


【python第五章——函数】相关推荐

  1. 第五章 函数和代码复用

    第五章 函数和代码复用 5.1 函数的基本使用 5.1.1 函数的定义 定义:函数是一段具有特定功能的.可重用的语句组,用函数名来表示并通过函数名进行功能调用. 使用函数的目的:降低编程难度和代码重用 ...

  2. 《Go语言圣经》学习笔记 第五章函数

    <Go语言圣经>学习笔记 第五章 函数 目录 函数声明 递归 多返回值 匿名函数 可变参数 Deferred函数 Panic异常 Recover捕获异常 注:学习<Go语言圣经> ...

  3. python 第五章 字典

    python 第五章 # # !/usr/bin/python # # -*- coding: utf-8 -*- # # @File : 总结.py # # @time : 2019-07-1010 ...

  4. stata:stata软件教程(人大十八讲)(5) 第五章 函数与运算符

    第五章 函数与运算符 5.1 运算符 exp 5.1.1 代数运算 5.1.2 字符运算 5.1.3 关系运算 5.1.4 逻辑运算 5.2 函数概览 function 5.3 数学函数 5.3.1 ...

  5. Python程序开发——第五章 函数

    目录 一.函数的定义 (一)def关键字定义函数 (二)形参和实参 (三)全局变量和局部变量 二.函数的调用 三.函数的参数传递 (一)必需参数 (二)关键字参数 (三)默认参数 (四)不定长参数 1 ...

  6. python第五章课后题答案_python程序设计基础(嵩天)第五章课后习题部分答案

    原博文 2019-10-13 13:50 − 第五章p1515.2:实现isodd()函数,参数为整数,如果参数为奇数,返回true,否则返回false.def isodd(s): x=eval(s) ...

  7. python第五章总结

    第5章组合数据类型 5.1认识组合数据类型 (1)常用的序列类型有字符串.列表和元组. (2)序列支持双向索引:正向递增索引和反向递减索引正向递增索引从左向右依次递增,第一个元素的索引为0,第二个元素 ...

  8. python第六章函数课后答案_浙大PTA-Python题库 函数题(6-1~6-6)题解

    其他各章题解链接如下 浙大PTA-Python题库 编程题第一章(1-1~1-3)题解 https://blog.csdn.net/zimuzi2019/article/details/1070206 ...

  9. Effective Python -- 第 2 章 函数(下)

    第 2 章 函数(下) 第 18 条:用数量可变的位置参数减少视觉杂讯 令函数接受可选的位置参数(由于这种参数习惯上写为 *args,所以又称为 star args,星号参数),能够使代码更加清晰,并 ...

最新文章

  1. 机器人 Ameca「苏醒」瞬间逼真到令人恐惧,网友纷纷惊叹……
  2. gensim中word2vec使用
  3. 这个重量级产业,中国正在爆发!
  4. 解决main.o(.data) type RW incompatible with bsp.o(.ARM.__AT_0x24001000) type ZI in er RW_IRAM2.
  5. 2019年,你需要关注这些Node API和Web框架
  6. 校验html输入值为电话号码,js验证输入是否为手机号码或电话号码示例
  7. linux服务器搭建_基于LINUX系统的邮件服务器搭建和详细部署(POSTFIX)
  8. bzoj1974 [Sdoi2010]代码拍卖会 循环+背包
  9. 【声学基础】概述——振动学
  10. 被迫开源的都是快要死的
  11. 【转】implicit declaration of function 这种警告问题的原因及解决方法
  12. excel设置单元格整数后还是有小数点_一招教你统一解决excel单元格的单位问题!...
  13. 【图像修复】基于matlab GUI运动模糊消除(逆滤波)【含Matlab源码 847期】
  14. win7计算机打开显卡设置在哪里,Win7系统nvidia控制面板在哪里?Win7系统nvidia控制面板设置方法...
  15. ps画画模糊笔刷_PS十个必须知道画笔的使用技巧
  16. 2021-08-26小白笔记
  17. mac双系统下在移动硬盘安装linux,MAC系统下外置移动硬盘安装windows双系统教程。...
  18. 关于vscode打感叹号无法输出html模板的解决方法
  19. python函数查询工具_布同:Python函数帮助查询小工具[v1和v2]
  20. CAD机械零件平面绘制练习七、CAD镜像命令高阶绘图练习

热门文章

  1. 唐朝乐队第三张专辑《浪漫骑士》6月上市.
  2. 测试用的美国信用卡账号
  3. Google(谷歌)高级搜索
  4. 华硕e202s安装linux系统,华硕笔记本E202S原装win10系统可以改win7吗?
  5. 关于Linux系统中文件名中带有空格问题分析
  6. Android 编译错误:CreateProcess error=206, 文件名或扩展名太长。
  7. Redis布隆过滤器与布谷鸟过滤器
  8. iOS Memory 内存详解
  9. 【小白向】简单随意DIY你的U盘图标
  10. INFOR SCE开发说明