IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python基础⑥-函数 -> 正文阅读

[Python知识库]python基础⑥-函数

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。—摘抄https://www.runoob.com/python/python-functions.html

函数基础

# 函数的三大特性
# 功能,参数,返回值
#### 有代码(有功能)
def factory():   #  制造一个工厂
	print('正在制造手机')  # 代码相对于员工或者机器
factory()
#### 无代码(有时候代码还没来得及写。但是有知道这段代码该做什么可以先定义好函数)
def shopping():
	pass
shopping()

在这里插入图片描述

函数各种参数

无参函数


# 参数
# 无参函数
# 应用场景仅仅只是执行一些操作,比如与用户交互,打印(工厂制造手机,不需要外接资源)
def factory():   #  制造一个工厂
 print('正在制造手机')  # 代码相对于员工或者机器
factory()

在这里插入图片描述

有参函数


# 有参
# 需要根据外部传进来的参数,才能执行相应的逻辑,计算 (工厂制造手机,需要a零件和b零件)
def factory(a,b):   #  制造一个工厂
    # 1 形参: 指的是在定义函数阶段括号内指定变量名,即形参本质就是"变量名"
    #  形参可以看做一个变量名
    print('a是%s'%a)
    print('b是%s'%b)
factory('小明','小王')

在这里插入图片描述

实参

指的是在调用函数阶段括号内传入的值,即实参本质就是"值"
调用函数的参数称为实参
形参与实参的关系:在调用函数时,会将实参(值)赋值(绑定)给形参(变量名)

位置传参

factory(3,2)
# 注意:但凡按照位置定义的形参,必须被实参传值,多一个不行,少一个也不行
# 位置参数 *****
# 错误示范
# factory(1,2,3)
# # factory(1)

在这里插入图片描述

关键字传参

#关键字实参: 
# 在调用函数阶段,按照key=value的形式指名道姓地为形参传值
#注意:
#1. 可以完全打乱顺序,但仍然能指名道姓为指定的形参传值
#2. 可以混合使用位置实参与关键字实参,但是必须注意:
#    2.1 位置实参必须放到关键字实参前面
#    2.2 不能对一个形参重复赋值
factory(b=1,a=2)
# 错误示范
# factory(a =1 ,a=2,b=2)
# factory(1,a=1,b=2)
# factory(a=2,2)
# 正确
factory(2,b=2)

在这里插入图片描述

默认参数


#默认参数  
#默认参数:指的是在定义函数阶段,就已经为某个形参赋值了,改形参称之为有默认值的形参,简称默认形参
#注意:
#1. 在定义阶段就已经被赋值,意味着在调用阶段可以不用为其赋值
#2. 位置形参应该放到默认形参前面
#3. 默认参数的值在函数定义阶段就已经固定死了
def factory(a,b=2):#  在定义阶段就已经被赋值,意味着在调用可以不用为其赋值,也可以对其重新赋值
    c = a + b
    print(c)

factory(1,5)

# 位置形参vs默认形参
# 对于大多情况下传的值都不相同的,应该定义成位置形参
# 对于大多情况下传的值都相同的,应该定义成默认形参

def register(name,age,sex='男'):
    print(name,age,sex)

register('小王',18)
register('小戴',18,'女')
register('小王',18)
register('小王',18)
register('小王',18)

在这里插入图片描述

不定长参数

带*参数

可变长度的参数(不定长参数)
在形参中带*:会将调用函数时溢出位置实参保存成元组的形式,然后赋值*后的变量名


def foo(x,y,*z):
    print(x,y,z)
    print(*z)
foo(1,2,3,4,5,6)

# 实参打散
foo(1,*(2,3))
foo(*(1,2,3))
foo(*[1,2,3])
foo(*'abc')

在这里插入图片描述

带**参数

在形参中带**:会将调用函数时溢出关键字实参保存成字典的形式,然后赋值**后的变量名

def foo(x,y,**z):
    print(x,y,z)

foo(1,2,a=1,b=2,c=3)
foo(1,y=1,a=1,b=2,c=3)

在这里插入图片描述

** 与* 混合使用

规范: 在形参中带*与**的,*后的变量名应该为args,**后跟的变量名应该时kwargs

def factory(*args,**kwargs):# * 接受的是0个到多个位置参数
    # ** 接受的是0个到多个关键字参数
    print(args)
    print(kwargs)
factory(1,2,3,x=3,y=4)
factory(*[1,2,3],**{'x':3,'y':4})

在这里插入图片描述

*加在 列表、元组、集合、字典前可以打散元素
**加在字典前可以打散字典成为关键字参数

print(*(1,2,3))
print(*[1,2,3])
print(*{1,2,3})
print(*{'name':'小王','age':18})
# **{'name':'小王','age':18} 

在这里插入图片描述

函数包装

# !!!!!!!!!!!!!!!当我们想要将传给一个函数的参数格式原方不动地转嫁给其内部的一个函数,
# 应该使用下面这种形式

def bar(x,y,z):
    print(x,y,z)
    
def wrapper(*args,**kwargs):
    bar(*args,**kwargs)
    
wrapper(1,2,3)

# 虽然调用的是wrapper,但是要遵循的确是bar定义的参数标准

在这里插入图片描述

多种参数混合

# 了解
# 命名关键字参数: 放到*与**之间的参数称之为命名关键字参数 ***
def foo(x,y,*args,m,n,**kwargs):
    print(x,y) # 1 2
    print(args) # (3, 4, 5, 6)放到元组
    print(m,n) # 3 4
    print(kwargs) # {'a': 1, 'b': 2, 'c': 3}
# # 错误
#foo(1,2,3,4,5,6,a=1,b=2,c=3)
# 正确
foo(1,2,3,4,5,6,m=3,n=4,a=1,b=2,c=3)

在这里插入图片描述

匿名函数

匿名函数:就是没有名字的函数
为何要用:
用于仅仅临时使用一次的场景,没有重复使用的需求
匿名函数,除了没有名字其他的都有
语法 lambda空格+参数+冒号+函数体代码(表达式或者函数)
一行代码图省事
像java中的lambda表达式

基本用法


# # 匿名函数的定义
print(lambda x,y:x+y)
# # 调用直接内存地址加括号(它虽然没有名字)+括号可以调用
# 返回值省去了return
# 表达式
print((lambda x,y:x+y)(1,2))
# # 函数
print((lambda x,y:print(x+y))(1,2))

在这里插入图片描述

巧妙利用匿名函数(简洁、美观、易懂)

对比两种取字典中最大值的方法。匿名函数非常的方便

# # 把内存地址赋值给一个变量没有意义
# # 匿名函数的精髓就是没有名字,为其绑定名字是没有意义的
#f=lambda x,y:x+y
#print(f(1, 2))
# 匿名函数与内置函数结合使用
# max,min,sorted
salaries = {
    'xiaowang':3000000,
    'xiaodai':10000,
    'xiaozhou':3000
}
# # 求薪资最高的那个人名:即比较的是value,但取结果是key
# # 默认比较key值
print(max(salaries))
# # max(字典,key=函数名)
def func(name):
    return salaries[name]
print(max(salaries, key=func))

# # 在外面我们不要用它
# # func(1)
# # 求最大值即比较的是value工资,但取结果是key人名
print(max(salaries, key=lambda name: salaries[name]))
#
# # 求最小值
print(min(salaries, key=lambda name:salaries[name]))
# sorted排序

在这里插入图片描述

nums = [11,33,22,9,1]
res = sorted(nums,reverse=True)
print(res)

# 循环遍历薪资
for v in salaries.values():
    print(v)

print(sorted(salaries.values()))
# 但是我们是要比较薪资,返回的却是人名
# 薪资反序
print(sorted(salaries, key=lambda name: salaries[name], reverse=True))
# 薪资正序
print(sorted(salaries, key=lambda name: salaries[name], reverse=False))

在这里插入图片描述

闭包函数

基本用法

闭包函数
闭指的是:该函数是一个内部函数
包指的是:指的是该内部的函数名字在外部被引用
即调用一个函数,返回的结果是另一个函数还能在调用

# 1、函数定义阶段:
# 只检测函数体的语法( 工厂合不合格),不执行函数体代码 (不使用工厂)
#def factory():#  制造一个工厂
    print('正在制造手机') # 代码相对于员工或者机器

# 2、函数调用阶段:
# 1 先找到名字   (找到工厂的位置)
# # 2 根据名字调用代码   ( 加了括号执行工厂进行加工)
#
#factory()

def outer():# 没有调用outer()
    #1 只检测函数体outer的语法( 工厂合不合格),不执行函数体代码 (不使用工厂)
    print('外面的函数正在运行')
    def inner():
        print('里面的函数正在运行')
    return inner # 3返回inner函数的内存地址  想象成一个钥匙 控制里面工厂
# 4 得到里面工厂的钥匙 钥匙取一个名字inner
inner=outer() #2 定义了inner函数# 是不是直接函数名加括号就可以调用呢?
# 5 里面钥匙加括号就可以开启里面的工厂
inner()

在这里插入图片描述

闭包传参

# 为函数体传值的方式一:参数
def func(x,y):
    print(x+y)

func(1,2)
func(1,2)


# 为函数体传值的方式二:闭包
def outer(x,y):

    def func():
        print(x + y)
    return func
#
# print(outer(1,2))
func=outer(1,2)
# print(func)
# 不用再次写参数可以达到传入1,2
func()
func()

闭包函数可以将参数封装好,这样就等于调用的时候不需要在重复指定参数。可以将一些不希望别人修改的参数封装成闭包函数
在这里插入图片描述

装饰器(很重要)

装饰器就是一个特殊的闭包函数
1、什么是装饰器(就是一个函数,只不过这个函数不是给自己使用的,是给其他函数添加功能的)
器指的是工具,而程序中的函数就具备某一功能的工具
装饰指的是为被装饰器对象添加额外功能,例如打印日志、校验参数等等
2、为什么要用装饰器
软件的维护应该遵循开放封闭原则
开放封闭原则指的是:
软件一旦上线运行后对修改源代码是封闭的,对扩展功能的是开放的
这就用到了装饰器
装饰器的实现必须遵循两大原则:
1、不修改被装饰对象的源代码(人的原来的性格,生活方式)
2、不修改被装饰对象的调用方式(人的原来的外貌,名字)

基本用法


# def run():
#     print('跑步')
#     print('健身')
# run()

# def fitness():
#     print('健身')
#     run()
# def run():
#     print('跑步')
#
# fitness()

# 装饰器其实就在遵循1和2原则的前提下为被装饰对象添加新功能
# 比如男孩1给女朋友买衣服,项链或化妆品  , 变的更加自信,原来的外貌,原来的性格没有发生改变 # 装饰器

# 比如男孩2带女朋友去整容   , 变的更加自信(不一定), 原来的外貌,原来的性格发生改变 # 不是装饰器
# 装饰器
name = '小王'
def run(name):
    print('=========')
    print('我是%s'%name)
    print('=========')
    return '你好:%s'%(name)
# run(name)
def decorate(func): # func等下我们要传入的run
    def new_func(name): #  run(name) 的name
        print('函数执行前的日志 参数: %s'%(name))
        res = func(name)
        print('函数执行后的日志 返回值: %s'%(res))
        return res
    return new_func
# 一 1.定义了new_func(name)函数 ,2.返回 了new_func内存地址 3.传入了一个run函数名
run=new_func=a=decorate(run)
#print(a)
print(run(name))

在这里插入图片描述

通过注解的方式使用装饰器

简化了 run=new_func=decorate(run) 这一步的连续赋值

name = '小王'
@decorate
def run(name):
    print('=========')
    print('我是%s'%name)
    print('=========')
    return '你好:%s'%(name)
# run(name)
def decorate(func): # func等下我们要传入的run
    def new_func(name): #  run(name) 的name
        print('函数执行前的日志 参数: %s'%(name))
        res = func(name)
        print('函数执行后的日志 返回值: %s'%(res))
        return res
    return new_func
print(run(name))

# 装饰器的要求高于闭包
#         1、不修改被装饰对象的源代码(人的原来的性格,生活方式)
#         2、不修改被装饰对象的调用方式(人的原来的外貌,名字)

在这里插入图片描述

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-10-04 12:48:17  更:2021-10-04 12:50:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 20:20:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计