day008|python之函数
函数
1 Type hinting
# Type hinting
def add(x: int, y: int) -> int:
    res = x + y
    return res
print(add.__annotations__)
# {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}
2 函数参数
2.1 概述
- 函数参数可以分为两大类
形参:在定义函数时,在括号内指定的参数/变量名,称之为形式参数,简称形参
形参的本质就是变量名
实参:在调用函数时,括号内传入的值,称之为实际参数,简称实参
实参的本质就是变量值 - 实参与形参的关系:在调用函数时,实参的值会绑定给形参,该绑定关系可以在函数内使用
在函数调用结束后,会解除绑定关系 
2.2 参数详解
- 位置形参
 
位置形参: 在定义函数时,按照从左到右的顺序依次定义的变量名,称之为位置形参
      特点:必须被传值,多一个不行,少一个也不行
def func(x, y):
    print(x, y)
func(1, 2)
func(1, 2, 3)       # 报错
func(1)             # 报错
- 位置实参
 
位置实参:在调用函数时,按照从左到右的顺序依次传入的值,称之为位置实参
      特点:按照位置与形参一一对应
def func(x, y):
    print(x, y)
func(1, 2)
func(2, 1)
- 默认形参
 
默认参数(具有默认值的形参):在定义函数时,就已经为某个形参赋值了,该形参就称之为默认参数
      特点:在调用阶段可以不用给默认形参传值
def func(x, y=111):
    print(x, y)
func(1, 2)          # 1 2
func(1)             # 1 111
def register(name, age, gender="male"):
    print(name, age, gender)
register("egon", 18)
register("lxx", 38)
register("hxx", 32, "female")
register("李建国", 30)
register("alex", 31)
register("xxx", 18)
- 关键字实参
 
关键字实参:在调用函数时,按照key=value的形式指定的实参,称之为关键字实参
      特点:可以打乱顺序,但仍能指名道姓为指定的形参赋值
def func(x, y=2222):
    print(x, y)
func(y=222, x=1212)         # 1212 222
func(x=111)                 # 111 2222
2.3 参数的使用
- 实参的混用
 
实参的混用:位置实参和关键字实参可以混用,但必须注意
  Ⅰ 位置实参必须放在关键字实参的前面
  Ⅱ 不能为同一个形参重复赋值
def func(x, y=2222):
    print(x, y)
func(1, y=2)              # 1 2
func(y=2, 1)            # 报错
func(1, y=2, x=3)       # 报错
- 形参的混用
 
形参的混用:位置形参和默认形参可以混用,但必须注意
  位置形参必须放在默认形参的前面
def func(x, y=111):
    print(x, y)
def func(y=111, x):     # 报错
    print(x, y)
- 默认形参使用的注意点
 
默认形参使用的注意点
   默认形参的值最好是不可变类型
m = 222
def func(x, y=m):
    print(x, y)
m = 666
func(111)               # 得到111 222
def register(name,hobby,hobbies=[]):
    hobbies.append(hobby)
    print('%s 的爱好是 %s' %(name, hobbies))
def register(name, hobby, hobbies=None):
    if hobbies is None:
        hobbies=[]
    hobbies.append(hobby)
    print('%s 的爱好是 %s' %(name, hobbies))
register("egon", "smoke")
register("lxx", "dance")
register("hxx", "drink")
2.4 可变长函数-->*与**的应用
可变长指的是在调用函数时,传入参数个数不固定,而实参是为形参赋值的
所以必须有对应格式的形参来接受溢出的实参
用在形参中
在形参中带*,*会将溢出位置实参汇总成元组,然后赋值给其后变量名,通常是args
def func(x, y, *z):
    print(x, y, z)
func(1, 2, 3, 4, 5)         # 1 2 (3, 4, 5)
func(1, 2)                  # 1 2 ()
func(1)                     # 报错
def my_sum(*args):
    res = 0
    for i in args:
        res += i
    print(res)
my_sum(1)               # 1
my_sum(1, 2)            # 3
my_sum(1, 2, 3)         # 6
在形参中带**,**会将溢出关键字实参汇总成字典,然后赋值给其后变量名,通常是kwargs
def func(x, y, **kwargs):
    print(x, y, kwargs)
func(1, y=2, a=1, b=2, c=3)        # 1 2 {'a': 1, 'b': 2, 'c': 3}
- 用在实参中
 
在实参中带*:*会将紧跟其后的实参打散成位置实参,注意*后跟的应该是一个可以被for循环循环的类型
def func(a, b, c, d):
    print(a, b, c, d)
func(*"hello")                        # 报错,不对应
func(*"hell")                           # h e l l
func(*[11, 22, 33, 44])                 # 11 22 33 44
func(11, 22, *[33, 44])                 # 11 22 33 44
func(11, 22, *{"k1": 111, "k2": 222})   # 11 22 k1 k2
在实参中带**:**会将紧跟其后的实参打散成关键字实参,注意*后跟的必须是一个字典
def func(a, b, c, d):
    print(a, b, c, d)
func(**{"k1": 333, "k2": 444})                              # 报错
func(**{"d": 333, "b": 444, "a": 111, "c": 222})            # 111 444 222 333
func(**[("d", 333), ("b", 444), ("a", 111), ("c", 222)])    # 报错
- 混用
 
混用
  Ⅰ 在形参中,*必须在**前
  Ⅱ 在实参中,*必须在**前
def index(x, y, z):
    print('index------>', x, y, z)
def wrapper(*arges, **kwargs):
    index(*arges, **kwargs)
# wrapper(1, 2, 3, 4, a=1, b=2, c=3)      # 不能一一对应 报错
wrapper(1, 2, 3)                # index------> 1 2 3
wrapper(z=3, y=2, x=1)          # index------> 1 2 3
def wrapper(*arges,**kwargs):
    print(arges)
    print(kwargs)
wrapper(1, 2, a=1,b=2,c=3)      # (1, 2) {'a': 1, 'b': 2, 'c': 3}
2.6 命名关键字形参
- 在*与**之间定义的形参
 - 必须按照key=value的形式传值
 
def func(x, y=1, *args, a=666, b, **kwargs):
    print(x)
    print(y)
    print(args)
    print(a)
    print(b)
    print(kwargs)
func(1, 2, 3, 4, 5, 6, 7, a=111, b=222, c=333)      # 1 2 (3, 4, 5, 6, 7) 111 222 {'c': 333}
func(1, 2, 3, 4, 5, 6, 7, b=222, c=333)             # 1 2 (3, 4, 5, 6, 7) 666 222 {'c': 333}
func(1, 2, 3, 4, 5, 6, 7, b=222, 333)               # 报错
3 函数对象
- 函数是第一等公民(可以当变量使用)
 
def func():
    print('from func')
3.1 可以赋值
f = func
f()             # 输出from func
3.2 可以当参数传给另一个函数
def bar(x):
    print(x)
mmm = 11111
bar(mmm)           # 11111
bar(func)          # <function func at 0x000002D4F29B63A0>
3.3 可以当作一个函数的返回值
def add(x):         # x=函数func的内存地址
    return x        # return 函数func的内存地址
res = add(func)     # 相当于add(函数func的内存地址)
print(res)          # <function func at 0x000002D4F29B63A0>
3.4 可以当容器类型的元素
x = 10
l = [x, func]
print(l)            # [10, <function func at 0x000002C48C4463A0>]
l[-1]()             # from func
# 练习
# 新的功能只需要在字典中加入即可,无需动循环
def login():
    print('login')
def register():
    print('register')
def transfer():
    print('transfer')
def withdraw():
    print('withdraw')
func_dic = {
    "1": [login, "登录"],
    "2": [register, "注册"],
    "3": [transfer, "转账"],
    "4": [withdraw, "提现"]
}
while True:
    print("0 退出")
    for k in func_dic:
        print(k, func_dic[k][-1])
    choice = input("请输入操作编号:").strip()
    if choice == "0":
        break
    if choice in func_dic:
        func_dic[choice][0]()
    else:
        print("输入的操作不存在")
4 函数嵌套
4.1 函数的嵌套定义
def f1():
    print('from f1')
    def f2():
        print('from f2')
    print(f2)
    f2()
    x=1111
f1()
输出结果如下:
# from f1
# <function f1.<locals>.f2 at 0x00000274E0EB8700>
# from f2
from math import pi
def circle(radius, mode=0):
    def perimiter(radius):
        return 2 * pi *radius
    def area(radius):
        return pi * (radius ** 2)
    if mode == 0:
        return perimiter(radius)
    elif mode == 1:
        return area(radius)
res1 = circle(10, mode=0)
print(res1)                 # 62.83185307179586
res2 = circle(10, mode=1)
print(res2)                 # 314.1592653589793
4.2 函数的嵌套调用
def max2(x, y):
    if x > y:
        return x
    else:
        return y
def max4(a, b, c, d):
    res1 = max2(a, b)
    res2 = max2(res1, c)
    res3 = max2(res2, d)
    return res3
res = max4(1, 2, 3, 4)
print(res)              # 4
												
											day008|python之函数的更多相关文章
- python的函数
		
函数一词起源于数学,但是在编程中的函数和数学中的有很大不同.编程中的函数式组织好的,可重复使用的,用于实现单一功能或相关联功能的代码块. 我们在学习过程中已经使用过一些python内建的函数,如pri ...
 - python strip()函数 介绍
		
python strip()函数 介绍,需要的朋友可以参考一下 函数原型 声明:s为字符串,rm为要删除的字符序列 s.strip(rm) 删除s字符串中开头.结尾处,位于 rm删除 ...
 - python  split()函数
		
Python split()函数 函数原型: split([char][, num])默认用空格分割,参数char为分割字符,num为分割次数,即分割成(num+1)个字符串 1.按某一个字符分割. ...
 - Python数学函数
		
1.Python数学函数 1.abs(x):取绝对值,内建函数 2.math.ceil(x):向上取整,在math模块中 3.cmp(x,y):如果 x < y ,返回-1:如果 x == y ...
 - Python回调函数用法实例详解
		
本文实例讲述了Python回调函数用法.分享给大家供大家参考.具体分析如下: 一.百度百科上对回调函数的解释: 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函 ...
 - Python之函数与变量
		
本节内容 函数介绍及其作用 函数的定义与调用 函数的参数说明 全局变量与局部变量 值传递和引用传递 一.函数的介绍及其作用 编程语言中的函数与数学中的函数是有区别的:数学中的函数有参数(输入),就会有 ...
 - Python基础-函数篇
		
本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 函数与函数式编程 1.面向对象: 华山派-- ...
 - 【C++实现python字符串函数库】strip、lstrip、rstrip方法
		
[C++实现python字符串函数库]strip.lstrip.rstrip方法 这三个方法用于删除字符串首尾处指定的字符,默认删除空白符(包括'\n', '\r', '\t', ' '). s.st ...
 - 【C++实现python字符串函数库】二:字符串匹配函数startswith与endswith
		
[C++实现python字符串函数库]字符串匹配函数startswith与endswith 这两个函数用于匹配字符串的开头或末尾,判断是否包含另一个字符串,它们返回bool值.startswith() ...
 
随机推荐
- Sec-Fetch-*请求头,了解下?
			
如果你使用76+版本的chrome浏览器,通过开发者面板查看每个网络请求,会发现都有几个Sec-Fetch开头的请求头,例如访问百度首页https://www.baidu.com/的请求: Sec-F ...
 - vue自定义指令 默认图片
			
/** * 检测图片是否存在 * @param url */ function imageIsExist(url) { return new Promise((resolve) => ...
 - 【转】Setting up SDL Extension Libraries on Windows
			
FROM: http://lazyfoo.net/tutorials/SDL/06_extension_libraries_and_loading_other_image_formats/window ...
 - 作为servlet容器的hi-nginx-java
			
hi-nginx-java是一个独立于java官方的servlet规范,它有能力把NGINX直接编成servlet容器服务器.换言之,无需安装tomcat等容器服务器,也无需使用nginx的反向代理功 ...
 - axios网络封装模块
			
功能特点 在浏览器中发送XMLHttpRequests请求 在node.js总发送http请求 支持Promise API 拦截请求和相应 转换请求和响应数据 axios请求方式 支持多种请求方式 a ...
 - php数据映射到echarts中国地图
			
echarts和php结合 根据php后台数据,映射到地图上所有的省份,地图市下钻的形式,每次下钻到新地图不合并(合并缩放的话会导致下钻地图位置找不到了),添加了自定义工具栏里面的返回到顶级下钻地图 ...
 - 4、Python语法之变量
			
一 引入 我们学习Python语言是为了控制计算机.让计算机能够像人一样去工作,所以在Python这门语言中,所有语法存在的意义都是为了让计算机具备人的某一项技能,这句话是我们理解后续所有Python ...
 - 使用bootstrap fileinput多文件拖拽上传的记录
			
今天琢磨文件上传,刚好看到bootstrap 我就搜了一下,刚刚能满足需求,使用上手也很快,使用完还是记录下来. 1.首先我们下载插件包,可以用nuget搜索bootstrap-fileinput 也 ...
 - php将富文本内容图片上传到oss并替换
			
/** * php 提取html中图片并替换 */ //要替换的内容 //提取图片路径的src的正则表达式 $match_str = '/(<img([^>]*)\s*src=(\'|\& ...
 - Java多线程经典题目(医院挂号)
			
题目 实现一个医院的挂号机系统,要求:有多台挂号机同时运行,此时无论有多少患者挂号,要求都能挂到不同 的号码,并且要求实现当意外断电之后,下一次恢复还能从上次结束号码继续挂号? * synchroni ...