目录

  • 一、函数介绍
    • 1.1 函数的定义与调用说明
  • 二、函数的定义
    • 2.1 函数定义说明
    • 2.2 定义函数的三种形式
  • 三、函数的调用
    • 3.1 函数调用说明
    • 3.2 调用函数的三种形式
  • 四、函数返回值
    • 4.1 函数返回值说明
    • 4.2 函数返回值的三种形式
    • 4.3 return两点注意事项
  • 五、函数的参数
    • 5.1 形参和实参
    • 5.2 有参函数的五种传参方式
      • 5.2.1 位置参数
      • 5.2.2 关键字参数
      • 5.2.3 默认参数
      • 5.2.4 命名关键字的函数参数定义形式
      • 5.2.5 可变长参数
      • 5.2.6 命名关键字参数
  • 六、总结

一、函数介绍

1.1 函数的定义与调用说明

函数名本质和变量类似(打印一个变量直接看到的结果是变量的值,这是因为在内部做了转化,为了能够看得更直观,打印函数直接看到的结果是一个内存地址,从底层上讲,变量名和函数名其实都是与内存地址对应的,因为定义的过程就是在开辟内存空间),所以函数名定义规则与定义变量名一致。函数就像是一个功能,这个功能就是要执行一个动作,所以约定俗成写成动词或者动词词组。

  • 具备某一个功能的工具就是程序中的函数;
  • 实现准备工具的过程就是函数的定义;
  • 把准备好的工具拿来用即为函数的调用;

所以函数的使用必须遵循:先定义,再调用。

二、函数的定义

2.1 函数定义说明

def 函数名(参数1,参数2,...):"""文档注释"""代码块1代码块2代码块3return 返回值# def:定义函数的关键字;
# 函数名:是用来调用函数的。函数名的命名必须能反映出函数的功能;
# 文档注释:描述该函数,来增强函数的可读性;
# 代码块:函数的功能实现代码;
# return:函数的返回值;

有了函数之后,如需实现以下打印功能,可以使用函数来完成:

# ##############################
# hello Albert
# ############################### 1. 先定义
def print_sym(sym, count):print(sym * count)def print_msg(msg):print('\033[045m%s\033[0m' % msg)  # \033[045m %s \033[0m 这部分代码的作用是改变输出的颜色# 2. 再调用(函数名加括号就是在调用函数)
print(print_sym)  # 函数名对应一个内存地址
print_sym('#', 30)
print_msg('hello Albert')
print_sym('#', 30)

2.2 定义函数的三种形式

  1. 有参函数:当函数体的功能依赖于传入的参数时,我们就使用有参函数。
def max2(x ,y):if x > y:print(x)else:print(y)max2(100, 101)
  1. 无参函数:当函数体的功能不使用传入的参数时,我们传入参数显然是没有必要的;
def func():print('---------------------------')print('--------soft run-----------')print('---------------------------')func()
  1. 空函数:函数体为pass,事先定义功能组织结构,通过调用函数执行某个功能;
def autn(username, password):"""这是一个用户认证功能:param username::param password::return:"""passdef put():"""上传功能:return:"""pass

三、函数的调用

3.1 函数调用说明

  • 函数的使用必须遵循:先定义,后调用的原则;
  • 注意:如果没有事先定义函数而直接调用,就相当于在引用一个不存在的变量名;
  • 定义阶段:在定义阶段只检测语法,不执行函数体代码;
  • 调用阶段:根据函数名找到函数的内存地址,然后执行函数体代码;
  • 函数名加括号即调用函数;

3.2 调用函数的三种形式

  1. 基本的调用;
def func():print('from func')
  1. 调用并把返回结果赋值给变量;
def max2(x, y):if x > y:return xelse:return yres = max2(10, 3)
  1. 把返回结果再当做参数传入;
res = max2(max2(10, 3), 11)

四、函数返回值

4.1 函数返回值说明

什么时候应该有返回值?
函数体代码运行完毕后需要有一个返回结果给调用者;

4.2 函数返回值的三种形式

  1. 没有return,或者return后面什么都不加,或者return后面加None;
def func():passdef func1():returndef func2():return None
  1. return后面跟一个常数值,返回该值本身;
def func3():return 1
  1. return可以使用逗号分割,返回多个值,会返回一个元组给调用者;
def fun4():return 1, 2, [1, 2, 3]res4 = func4()
print(res4)  # 输出为(1, 2, [1, 2, 3])

4.3 return两点注意事项

  1. return返回值没有类型限制;
  2. return是函数结束的标志,函数内可以写多个return,但执行一次,函数就立刻结束,并把return后的值作为本次调用的返回值;

五、函数的参数

5.1 形参和实参

  • 形参(形式参数):指的是在定义函数时,括号内定义的参数,形参其实就是变量名;
  • 实参(实际参数):指的是在调用函数时,括号内传入的值,实参其实就是变量的值;

注意:
实参值(变量的值)与形参(变量名)的绑定关系只在函数调用时才会生效/绑定,在函数调用结束后立刻解出绑定;

5.2 有参函数的五种传参方式

5.2.1 位置参数

位置参数是最基本的传参方式。位置即顺序,位置参数指的就是按照从左到右的顺序依次定义的参数;

# 在定义函数时,按照位置定义的形参,称为位置形参
def foo(x, y, z):print(x, y, z)"""
注意:
位置形参的特性是:在调用函数时必须为其传值,多一个不行,少一个也不行
"""# 在调用函数时,按照位置定义的实参,称为位置实参# foo(1, 2)  # 报错
foo(1, 3, 2)  # x=1, y=3, z=2

5.2.2 关键字参数

在调用函数时,按照key=value的形式定义的实参,称为关键字参数。关键字参数是指在位置形参的前提下,以关键字的形式为形参传值,所以它与位置参数的区别主要体现在实参的传值上面;

def foo(x, y, z):print(x, y, z)foo(x=1, y=3, z=2)"""
注意:
1、相当于直呼其名地位形参传值,意味着即便不按照顺序定义,仍能为指定的参数传值
foo(y=2, x=1, z=3)  # x=1, y=2, z=32、在调用函数时,位置实参与关键字实参可以混合使用,但必须遵循形参的规则
foo(1, 2, z=3) 3、不能为同一个形参重复传值
foo(1, x=1, y=3, z=2)  # 报错4、位置实参必须放到关键字实参的前面
foo(y=3, z=2, 1)  # 报错
"""

5.2.3 默认参数

默认参数指的是在定义阶段已经为某个形参赋值,那么该形参就称为默认参数;

# 1、定义阶段已经有值,意味着调用阶段可以不传播
def register(name, age, sex='male')print(name, age, sex)register('Albert', 18, )
register('林志玲', 20, ‘female’)# 2、位置形参必须在默认参数的前面
def func(y=1, x):  # 报错pass# 3、默认形参的值只在定义阶段赋值一次,也就是说默认参数的值在定义阶段就固定死了
m = 10
def foo(x, y=m)print(x, y)
m = 'a'  # foo内的默认参数不会发生改变# 4、默认参数的值应该设置为不可变类型# 假如默认参数不是不可变类型,我们以列表为例
def register(name, hobby, l=[]):l.append(hobby)print(name, l)register('kobe', 'play')  # kobe ['play'] 一切正常
register('james', 'read')  # james ['play', 'read']
register('Albert', 'music')  # Albert ['play', 'read', 'music'] 这就是未设置为不可变类型出现的BUG# 数据出错的原因就是每次调用都会在同一个列表上作修改# 为了实现同样的功能,修正后如下
def register(name, hobby, l=None):if l is None:l = []l.append(hobby)print(name, l)register('kobe', 'play')  # 每一次调用的时候,l的默认参数都是None,因此每次都会新建一个[]
register('james', 'read')
register('Albert', 'music')# 应用场景
# 对于经常需要变化的值,需要将对应的形参定义成位置形参
# 对于大多数情况值都一样的情况,需要将对应的形参定义成默认参数

5.2.4 命名关键字的函数参数定义形式

python提功了一种命名关键字的函数参数定义形式,利用“*”定义参数名称,“*”后的参数在函数调用时必须明确写上参数名称。

def print_info(name,age,*,job,home):print("{},{},{},{}".format(name,age,job,home))print_info("Jack",12,job="Student",home="China")

上述代码中在“”*前面的两个参数name和age在函数调用时不需要编写参数名称,而在“*”后面定义的两个参数在函数调用时必须编写参数名称。

5.2.5 可变长参数

<1> 可变长参数基本使用

可变长度指的是参数的个数可以不固定,实参有按位置定义的实参和按关键字定义的实参,所以可变长的实参指的就是按照这两种形式定义的实参个数可以不固定。然而实参终究是要给形参传值的,所以形参必须有两种对应的解决方案来分别处理以上两种可变长度的实参。

注意可变参数的数据类型为元组,可以用for执行循环处理。

# *会将溢出的位置实参全部接受,然后保存成元组的形式赋值给一个变量args(可以任意命名,约定俗成是args)
def foo(x, y, z, *args):  # args = (4, 5, 6, 7, 8)print(x, y, z)  # 输出1,2,3print(args)  # 输出(4, 5, 6, 7, 8)foo(1, 2, 3, 4, 5, 6, 7, 8)# **会将溢出的关键字实参全部接收,然后保存成字典的形式赋值给kwargs
def foo(x, y, z, **kwargs):  # kwargs = {'c':3, 'a':1, 'b':2}print(a, y, z)print(kwargs)foo(x=1, y=2, z=3, a=1, b=2, c=3)

<2> 星与星星(打散)

很多时候[*]的作用就是打散

# 一旦遇到实参加*,就把该实参的值打散
def foo(x, y, z, *args):print(x, y, z)print(args)foo(1, 2, 3, *[4, 5, 6, 7, 8])  # foo(1, 2, 3, 4, 5, 6, 7, 8)
foo(1, 2, 3, *(4, 5, 6, 7, 8))  # foo(1, 2, 3, 4, 5, 6, 7, 8)
foo(1, 2, 3, *'hello')  # foo(1, 2, 3, 'h', 'e', 'l', 'l', 'o')def foo(x, y, z):print(x, y, z)#  foo(*[1, 2, 3, 4])  # foo(1, 2, 3, 4)  报错
foo(*[1, 2, 3])  # foo(1, 2, 3) # 一旦碰到实参加**,就把该实参的值打散
def bar(x, y, z, **kwargs):print(x, y, z)print(kwargs)bar(1, 2, 3, **{'a': 1, 'b': 2})  # foo(1, 2, 3, b=2, a=1)def boo(x, y, z):print(x, y, z)# boo(1, **{'z':3, 'y':2, 'x':111})  # 报错 boo(1, z=3, y=2, x=111)
boo(1, **{'z':3, 'y':2})  # foo(1, z=3, y=2)# *的应用场景
def sum2(*args):res = 0for num in args:res += numreturn resprint(sum2(1, 2, 3, 4, 5, 6, 7, 8))# **的应用场景
def auth(name, pwd, **kwargs):print(name)print(pwd)print(kwargs)auth(name='Albert', pwd='123', group='group1')

<3>组合使用(重点)

def index(name, age, gender)print('welcome %s %s %s' % (name, age, gender))def wrapper(*args, **kwargs):"""执行过程:wrapper的所有参数都原封不动地传给index,而index函数只接收三个位置参数星与星星的组合使用在源码中非常常见,这也是装饰器的核心之一,这非常重要"""index(*args, **kwargs)wrapper(name='Albert', age=18, gender='male')
wrapper('Albert', age=18, gender='male')
wrapper('Albert', 18, gender='male')
wrapper('Albert', 18, 'male')

5.2.6 命名关键字参数

<1>命名关键字参数导入

在[*]后面参数都是命名关键字参数,它的特点是必须被传值,约束函数的调用者必须按照key=value的形式传播,约束函数的调用者必须用指定的key名。

也就是说,**kwargs的数据形式为字典。

def auth(*args, **kwargs):"""使用方式auth(name='Albert',pwd='123')"""if len(args) != 0:print('必须用关键字的形式传参')returnif 'name' not in kwargs:print('必须用指定的key名name')returnif 'pwd' not in kwargs:print('必须用指定的key名pwd')name = kwargs['name']pwd = kwargs['pwd']print(name, pwd)print(help(auth))  # 打印文档注释auth(x='Albert', y='123')
auth('Albert', '123')
auth('Albert', pwd='123')
auth(name='Albert', pwd='123')

<2>命名关键字参数使用

# 使用命名关键字参数
def foo(x, y, *, z):print(x, y, z)# foo(1, 2)
# foo(1, 2, a=3)  # 报错
foo(1, 2, z=3)# 其实命名关键字参数的核心是*,args只是一个变量,有或者没有并不影响
def auth(*args, name, pwd)print(name, pwd)auth(pwd='123', name='Albert')# 使用命名关键字参数之后,可以接受参数的最复杂的情况
def foo(x, y=1, *args, z, m=2, **kwargs):  # m=2是关键字参数的默认值, **kwargs的作用是保存溢出的关键字参数一般情况下,foo1和foo2这两种就够用了
def foo1(x, y=1):passdef foo2(x, *args, **kwargs):pass

六、总结

  1. 知道什么是空函数,空函数的作用;
  2. 知道怎么输出一个函数所在的内存地址,print(fun());
  3. 知道怎么输出一个函数的文档注释,print(help(func()));
  4. 知道函数返回值的三种形式,(1)没有return或者return(None);(2)返回一个常数值;(3)返回用逗号分隔的多个值,会返回一个元组;
  5. 知道函数参数的可变长参数,*args和**kwargs的作用;

python编程高手之路——函数调用相关推荐

  1. Python编程高手之路——第二章:流程控制

    二.流程控制 2.1 运算方式 计算机的核心部件是CPU,CPU有两个功能,控制和运算: 2.1.1 数学运算 print(a ** b) # 幂 print(a // b) // 取整数 2.1.2 ...

  2. Python编程高手之路——第一章:用户交互

    一.编程入门 1.编程语言的划分 编程语言分为机器语言.汇编语言.高级语言 1.1 机器语言 机器语言是用二进制数字0和1进行编程,机器语言是人站在计算机的角度去编程,编程开发效率低,程序运行效率高. ...

  3. Python编程高手之路——第三章:数据类型

    三.数据类型 3.1 数据类型 3.1.1 数字类型int和float 数字类型即变量的值,如age=18,18就是我们保存的值: 变量是用来反映/保存状态以及状态变化的,针对不同的状态应该用不同的数 ...

  4. python数据结构编程_写给Python编程高手之 数据结构

    python视频教程栏目介绍Python编程需要注意的关键点. 如何在列表,字典,集合中根据条件筛选数据 案例:如何在下列列表data中筛选出大于0的数data = [1, -1, 2, 3, 4, ...

  5. 通往编程高手之路:《深入理解操作系统》

    亚达斯密在其经济学巨著<国富论>中提出了"看不见的那只手"的概念,意指市场机制对经济发展的作用,作为普通的个人来说我们在平时的生活中可能很难感受到市场机制所发挥的作用, ...

  6. 编程高手之路——闭包函数

    目录 一.函数嵌套调用 1.1函数嵌套调用 1.2 函数嵌套定义 二.名称空间 2.1 名称空间说明 2.2 名称空间的分类 三.作用域 3.1 变量作用域 3.1.1 参数名称的另一种定义形式: 3 ...

  7. python编程高手教程_写给编程高手的Python教程(11) 深入类和对象

    学习使我快乐 鸭子类型和多态 当看到一只鸟走起来像鸭子.游泳起来像鸭子.叫起来也像鸭子,那么这只鸟就可以被称为鸭子. 例如下面三个类(Cat.Dog.Duck)的定义中都定义了say方法 class ...

  8. python编程高手教程_写给编程高手的Python教程(01) 数据结构

    如何在列表,字典,集合中根据条件筛选数据 案例:如何在下列列表data中筛选出大于0的数 data = [1, -1, 2, 3, 4, 7] 复制代码 使用filter函数,第一个参数为一个函数,也 ...

  9. 马云都退休20天了,2019年剩下不到100天了:你还没掌握Python 编程思维吗?

    (800G全学习路径资料,免费领取↓) 看了两个视频,敲了几行代码,就天真的以为Python 很简单,可以自学成才? 那你准备好,我要告诉你一个扎心的事实: 1.学习资料多,学习找不到重点,别人踩过的 ...

最新文章

  1. python输入多个数字后续操作_有效地确定后续数字范围中的数字是否在有序列表中. (在Python中)...
  2. 把有限的精力放在最有意义的事上
  3. 虚拟服务器设置upnp,TP-Link路由器如何设置UPNP开启【设置步骤】
  4. 【学习笔记】智能制造问与答
  5. Angular reducer第一次被框架调用的单步调试细节
  6. python学习类型转换_Python学习总结5:数据类型及转换
  7. Docker for Windows使用简介
  8. 运算符面试题(剑指offer,面试宝典,牛客网)
  9. 用Python标准库turtle画一头金牛,祝您新年牛气冲天!
  10. maven开发web项目的福音,runJettyRun插件使用
  11. 不止鸿蒙 OS,华为的备用操作系统还有“极光”?
  12. jq select 操作
  13. linux自动加密软件开发,【天锐绿盾加密软件支持Linux_信息安全管理系统_文件自动加密_文档加密_图纸加密_网络实时监控_网络行为管理_内网安全的软件系统】免费在线试用_文档管理_选软件网...
  14. Gephi教程-根据邻接矩阵构建复杂网络有向图
  15. wsdl2java 工具_CXF中 wsdl2java工具的使用方法
  16. 模2运算_模二除法和CRC循环冗余校验
  17. AndroidStudio使用properties资源文件
  18. mysql on是什么意思_这SQL语句里的ON 是什么意思啊
  19. 量子计算机应用于哪些领域,量子计算的应用领域
  20. java反射机制详解篇一(基础)

热门文章

  1. 给 npm script 传递参数和添加注释
  2. Java 11 正式发布,新特性解读
  3. Docker教程(三) Docker网络访问和数据管理
  4. Docker Compose运行MySQL、Redis服务
  5. Docker快速部署PostgreSQL服务
  6. vuejs 指令封装 button 加载效果_这些Vue自定义指令,让你的项目开发爽到爆
  7. C#开发笔记之22-C#中的int、long、float、double等类型都占多少个字节的内存。
  8. 【java】测试dubbo业务
  9. 如何使用Postman和Newman在CI环境中自动化REST API端到端测试
  10. github编程语言排名_这是每种主要编程语言的Hello World应用示例-全部在一个GitHub存储库中