Python函数
Posted tcy1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python函数相关的知识,希望对你有一定的参考价值。
函数
"""
1.什么是函数
函数其实就是工具
如果没有函数就类似于每一次要使用锤子的时候
需要自己原地起锅烧火打造
2.为什么要有函数
为了节省人力、减少代码冗余
3.如何定义及使用函数
"""
# 函数的基本格式
"""
def func(参数1、参数2...):
‘‘‘函数的注释‘‘‘
函数体代码(就是真正的功能)
return 函数的返回值
1.def是定义函数的关键字
2.func是函数名 指向内存空间中的函数体代码
函数名的命名规范跟变量名一致
3.参数1、参数2在调用函数的时候可能需要传入的外部数据
4.函数的注释
用来解释函数的功能及使用的注意事项等等
5.函数体代码
实现该函数功能的实际代码
6.return返回值
在调用完函数之后 得到的结果
"""
函数的返回值
# 关键字return
def index():
name = ‘jason‘
# return 123
# return 123,1,2,3,4,5,6
return 123,‘jason‘,11.11,{‘username‘:‘jason‘}
print(‘会不会打印我‘)
# 1 函数没有return 默认返回None
# res = index()
# print(res) # None
# 2 就算有return后面如果什么都没有 还是返回None
# res = index()
# print(res) # None
# 3 return后面跟什么 函数就返回什么
# res = index()
# print(res) # 123
# 3.1 如果后面有多个数据 自动组织成元组返回
# print(res) # (123, 1, 2, 3, 4, 5, 6)
# 3.2 支持多个并且可以是任意数据类型
# print(res) # (123, ‘jason‘, 11.11, {‘username‘: ‘jason‘})
# ps:如果一个函数有多个返回值 那么我们很有可能会直接使用解压赋值
# a,b,c,d = index()
# print(a,b,c,d)
"""
return可以返回值
并且在函数体内部一旦遇到return
函数会立刻结束
"""
函数的参数分类
def index(x,y): # x和y就是形式参数
print(x,y)
index(1,2) # 1和2就是实际参数 将1赋值给x 将2赋值给y
"""
函数的参数分为两大类
形式参数
函数在定义阶段括号内指定的变量名叫形式参数
简称为形参
实际参数
函数在调用阶段括号内指定的数据 叫实际参数
简称为实参
两者之间的关系其实就相当于
形参是变量名
实参是变量值
传参调用函数其实就是给形参赋值
"""
函数的参数
# 位置参数
# def my_max(x,y):
# print(x,y)
# my_max(1,2) # 1 2
# my_max(1) # 少传一个不行
# my_max(1,2,3) # 多传一个也不行
# 默认参数
# 不传有默认的 传了就用自己的
# def register(name,gender=‘male‘):
# print(name,gender)
# register(‘jason‘,‘male‘)
# register(‘jason‘,‘male‘)
# register(‘jason‘,‘male‘)
# register(‘jason‘,‘male‘)
# register(‘jason‘,‘male‘)
# register(‘jason‘,‘male‘)
# register(‘jason‘,‘male‘)
# register(‘frank‘,‘female‘)
# register(‘haoda‘,‘others‘)
# register(‘jason‘)
# register(‘jason‘)
# register(‘jason‘)
# register(‘jason‘)
# register(‘shanshan‘,‘female‘)
# 关键字参数
# def register(name,gender):
# print(name,gender)
# register(1,2)
# register(2,1)
# register(gender=2,name=1) # 指名道姓的传 打破位置限制
# 混合使用
# register(gender=2,1) # 位置参数不能出现在关键字参数的后面
# register(1,gender=2)
# register(1,name=2) # 在一次调用中 一个形参不能重复的赋值
"""
参数的顺序
越短的越靠前
越长的越靠后
"""
# 可变长参数
def index(x,*a,**k):
print(x,a,k)
# 函数无论接收多少参数都能够正常执行
# index(1,2) # 1 (2,)
# index(1,2,3,4,5,6,7,8,9,0) # 1 (2, 3, 4, 5, 6, 7, 8, 9, 0)
# index(1) # 1 ()
# index(x=1,y=2,z=3) # 1 () {‘y‘: 2, ‘z‘: 3}
index(1,2,3,4,5,y=2,z=3) # 1 (2, 3, 4, 5) {‘y‘: 2, ‘z‘: 3}
"""
*号在形参中 用来接收多余的位置参数
组织成元组的形式赋值给后面的变量名
**号在形参中 用来接收多余的关键字参数
组织成字典的形式赋值给后面的变量名
虽然*和**后面的变量名没有固定的值,但是一般情况下我们会默认写成
*args
**kwargs
"""
def login(*args,**kwargs):
print(123)
login(1,2,3,4,5,6,7,7)
login(x=1,y=2,z=3)
login(1,2,3,4,5,6,7,7,x=1,y=2,z=3)
"""
*号在实参中
能够将列表、字符串打散 将打散成位置参数
**号在实参中
能够将字典打散成关键字参数
"""
def index(*args,**kwargs):
print(‘args:‘,args)
print(‘kwargs:‘,kwargs)
l = [1,2,3,4,5,6,7,8,9,0]
d = {‘username‘:"jason",‘password‘:123}
# index(l) # args: ([1, 2, 3, 4, 5, 6, 7, 8, 9, 0],) index(1,2,3,4,5,6,7,8,9,0)
# index(*l) # args: (1, 2, 3, 4, 5, 6, 7, 8, 9, 0)
# index(d) # args: ({‘username‘: ‘jason‘, ‘password‘: 123},)
index(**d) # kwargs: {‘username‘: ‘jason‘, ‘password‘: 123}
index(username=‘jason‘,password=123)
函数对象
# def index():
# print(‘from index‘)
# 1 函数名可以被当做变量名赋值给其他变量
# print(index)
# f = index
# # print(f)
# # index()
# f()
# 2 函数名可以当做函数的参数传入
# def index():
# print(‘from index‘)
# name = ‘jason‘
# def func(x):
# print(x)
# x()
# func(index)
# 3 函数名还可以当做函数的返回值(******)
# def bar():
# print(‘from bar‘)
#
# def index():
# print(‘from index‘)
# return bar
# res = index()
# res() # bar()
# 4 函数名还可以作为容器类型(能够存储多个元素的数据类型)的元素
def bar():
print(‘from bar‘)
l = [1,2,3,4,5,6,bar]
l[-1]()
函数的嵌套定义、调用
def index():
print(‘from index‘)
def inner():
print(‘from inner‘)
# return inner
inner()
res = index()
名称空间与作用域
"""
名称空间
name = ‘jason‘ 名称空间其实就是用来存储名字和值绑定关系的地方
内置名称空间
python解释器启动之后就会自动创建的名称空间
这个里面存放的是python解释器事先给你准备好的一些名字
len、max、min...
全局名称空间
在文件级别定义的
name = ‘jason‘
if 1:
age = 18
while True:
gender = ‘male‘
def index():
pass
局部名称空间
在函数体内部定义的
调用函数的时候创建 函数结束之后销毁
"""
# 名称空间的查找顺序
"""
你要先确定你当前在哪
"""
# print(len) # 内置
# len = ‘有点饿了‘
def index():
# len = ‘我也很饿‘
print(len)
# print(len)
index()
"""
内置 <== 全局 <== 局部
1.如果你当前在全局的话
这个时候查找顺序是
全局 >>> 内置
2.如果你当前在局部
这个时候查找顺序是
局部 >>> 全局 >>> 内置
"""
# 作用域
"""
局部作用域
局部名称空间
全局作用域
内置、全局名称空间
"""
# name = ‘jason‘
# def index():
# name = ‘frank‘ # 自己在自己的局部名称空间中创建了一个名字name
# index()
# print(name)
# 局部修改全局
# name = ‘jason‘
# def index():
# global name # 声明我要修改全局里面的name而不是创建
# name = ‘frank‘ # 自己在自己的局部名称空间中创建了一个名字name
# index()
# print(name)
# 局部修改局部
def func():
name = ‘haoda‘
def index():
name = ‘jason‘
def inner():
nonlocal name
name = ‘egon‘
# print(name)
inner()
print(name)
index()
func()
小补充
1.交叉赋值
m = 1
n = 2
# m = n
# n = m
# print(m,n)
# tmp = m
# m = n
# n = tmp
# print(m,n)
# 交叉赋值
m, n = n,m
print(m,n)
2.pass用法
def register():
pass
def register1():
...
装饰器
"""
装饰器
在不改变被装饰对象(函数)
1.调用方式
2.源代码
的基础之上给被装饰对象(函数)添加额外的功能
"""
# 提前书写装饰器的固定代码
def outer(func):
def inner(*args,**kwargs):
print(‘在执行被装饰函数之前你可以添加的额外操作‘)
res = func(*args,**kwargs)
print(‘在执行被装饰函数之后你可以添加的额外操作‘)
return res
return inner
@outer # index = outer(index)
def index():
print(‘from index‘)
# index()
print(index)
# 你们只需要熟悉无参装饰器即可
# 有参装饰器
def login_auth(x):
def outer(func):
def inner(*args,**kwargs):
print(‘在执行被装饰函数之前你可以添加的额外操作‘)
res = func(*args,**kwargs)
print(‘在执行被装饰函数之后你可以添加的额外操作‘)
return res
return inner
return outer
@login_auth(123)
def home():
pass
递归
"""
递归
函数在调用阶段 自己直接或者间接的又调用了自己
"""
def index():
print(‘from index‘)
index()
index()
import sys
print(sys.getrecursionlimit())
"""
不能无限制的递归,没有实际意义
1.递归的次数必须是有限的
2.每一次递归都要比上一次复杂度更低
包含两个过程
递推
回溯
"""
age(5) = age(4) + 2
age(4) = age(3) + 2
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 18
def get_age(num):
if num == 1:
return 18
return get_age(num-1) + 2
# 递归案例
l = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,]]]]]]]]]]]
def get_value(l):
for i in l:
if not isinstance(i,list):
print(i)
else:
get_value(i)
get_value(l)
二分法
"""
算法
其实就是解决问题的高效率的方法
"""
二分法
"""
二分法
参考的数据必须有大小顺序
"""
num_list = [13,15,17,23,55,78,98,123,234,345,453,567,657,713,890]
target_num = 23
def b_search(num_list,target_num):
# 代码优化 值不存在的情况
if len(num_list) == 0:
print(‘要找的数字不在这个列表内‘)
return
# 先获取中间索引值
middle_index = len(num_list) // 2
# 判断要找的数字于中间索引对应的值孰大孰小
if target_num > num_list[middle_index]:
# 截取右半边大的部分
num_list = num_list[middle_index+1:]
search(num_list,target_num)
elif target < num_list[middle_index]:
# 截取左半边小的部分
num_list = num_list[0:middle_index]
search(num_list,target_num)
else:
print(‘find it!‘)
三元表达式、生成器
# 判断两个数的最大值
# def index(x,y):
# # if x > y:
# # print(x)
# # else:
# # print(y)
# # 三元表达式
# return x if x > y else y
"""
三元表达式只适用于两选一的情况
x if x > y else y
如果if后面的条件成立那么返回if前面的值
如果条件不成立那么返回else后面的值
"""
# x = 1
# y = 10
# res = x if x > y else (y if y > x else 666)
# print(res)
# name = input(‘username>>>:‘)
# res = ‘NB‘ if name == ‘jason‘ else ‘垃圾‘
# print(res)
# 列表生成式
# l = [‘jason‘,‘frank‘,‘tony‘,‘tom‘,‘haoda‘]
# # 以前的套路
# # new_l = []
# # for name in l:
# # new_l.append(name+‘_NB‘)
# # print(new_l)
#
#
# # 列表生成式
# # res = [name+‘_DSB‘ for name in l]
# res = [name+‘_DSB‘ for name in l if name==‘jason‘] # [‘jason_DSB‘]
# print(res)
# 生成器表达式
# l = [‘jason‘,‘frank‘,‘tony‘,‘tom‘,‘haoda‘]
# res = (name+‘_DSB‘ for name in l) # <generator object <genexpr> at 0x000002D5F0F26048>
# for i in res:
# print(i)
"""
生成器能够节省内存 是我们程序优化阶段需要考虑的事情
"""
匿名函数
"""
没有名字的函数
一般情况下都是结合内置函数一起使用的
"""
res = lambda x,y:x+y
ret = res(1,2)
print(ret)
def index(x,y):
return x + y
salaries = {
‘egon‘:30000,
‘jason‘:888888888,
‘nick‘:2000,
‘tank‘:100
}
# print(max(salaries))
# """
# A-Z 65-90
# a-z 97-122
# """
def index(name):
return salaries[name]
# res = max(salaries,key=index)
res = max(salaries,key=lambda name:salaries[name])
print(res)
模块
"""
其实就是一系列功能的集合体
1.内置模块
2.第三方模块
3.自定义模块
"""
# 导入模块的方式
1.import...
2.from...import...
# 起别名
import mymd as md
md.index()
3.from mymd import *
index()
print(name)
# 如何导入第三方模块
1.利用pip3下载对应的模块
2.然后再利用上述import或者from import导入即可
常用模块
# import mymd
"""
将mymd里面所有的资源导入到当前文件
导入模块其实就是从上往下执行该模块代码
重复导入一个模块 只会生效一次
其余的语句不会起作用
"""
# print(mymd.index())
# print(mymd.name)
# from mymd import name
# import mymd as md
# md.index()
# from mymd import *
# index()
# print(name)
# 时间模块 time datetime
# import time
# print(time.time()) # 1595666567.451175
# time.sleep(3)
# print(‘宝贝你醒啦 么么哒‘)
# print(time.strftime(‘%Y-%m-%d‘))
# print(time.strftime(‘%Y-%m-%d %X‘))
# print(time.strftime(‘%Y-%m-%d %H:%M:%S‘))
import datetime
# print(datetime.datetime.now())
# print(datetime.date.today())
"""
2020-07-25 16:47:24.534835
2020-07-25
"""
# timedelta对象
# 可以对时间进行运算操作
import datetime
# 获得本地日期 年月日
# tday = datetime.date.today()
# 定义操作时间 day=7 也就是可以对另一个时间对象加7天或者减少7点
# tdelta = datetime.timedelta(days=7)
# 打印今天的日期
# print(‘今天的日期:{}‘.format(tday))
# 打印七天后的日期
# print(‘从今天向后推7天:{}‘.format(tday + tdelta))
# 总结:日期对象与timedelta之间的关系
"""
日期对象 = 日期对象 +/- timedelta对象
timedelta对象 = 日期对象 +/- 日期对象
"""
# 小练习 计算举例今年过生日还有多少天
# birthday = datetime.date(2000, 1, 21)
# now_date = datetime.date.today()
# days = birthday - now_date
# print(‘生日:{}‘.format(birthday))
# print(‘今天的日期:{}‘.format(now_date))
# print(‘距离生日还有{}天‘.format(days))
# 随机模块random
import random
# print(random.randint(1,6)) # 1到6随机的整数
# print(random.random()) # 0到1之间的小数
# l = [1,2,3,4,5,6,7,8,9]
# random.shuffle(l)
# print(l)
# l = [‘1号技师‘,‘2号技师‘,‘3号技师‘,‘4号技师‘,‘5号技师‘]
# res = random.choice(l)
# print(res)
# 搜狗笔试题
# 生成五位数的随机验证码 要求
# 每一位都是可以是数字、小写字母、大写字母
code = ‘‘
for i in range(5):
# 每次都随机产生一个数字
random_int = str(random.randint(0,9))
# 每次都随机产生一个小写字母
random_lower = chr(random.randint(97,122))
# 每次都随机产生一个大写字母
random_upper = chr(random.randint(65, 90))
# 三者选一个
temp = random.choice([random_int,random_lower,random_upper])
# 拼接
code += temp
print(code)
os与sys
os跟操作系统打交道的
sys是跟解释器打交道的
import os
# os.path.join()
res = os.path.getsize(r‘D:ln_day02‘)
print(res)
"""
拼接路径的时候 不同的操作系统分隔符是不一样
"""
import sys
print(sys.getrecursionlimit()) # 1000
序列化模块
"""
json格式数据
1、不同语言之间的数据交互
2、其实就是一堆字符串
"""
import json
d = {‘username‘:‘jason‘,‘password‘:123}
# res = json.dumps(d) # 将数据转成字符串的过程 就叫序列化
# print(res,type(res)) # {"username": "jason", "password": 123} <class ‘str‘>
#
# res1 = json.loads(res) # 将json格式的字符串转换成编程里面的数据类型 反序列化
# print(res1,type(res1)) # {‘username‘: ‘jason‘, ‘password‘: 123} <class ‘dict‘>
"""
encode
decode
"""
# with open(‘a.txt‘,‘w‘,encoding=‘utf-8‘) as f:
# json.dump(d,f)
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘) as f:
res = json.load(f)
print(res,type(res))
加密模块
# 加密模块
# import hashlib
# md5 = hashlib.md5()
# md5.update(b‘123‘) # 数据必须是bytes类型
# # md5.update(b‘h‘) # 数据必须是bytes类型
# # md5.update(b‘ell‘) # 数据必须是bytes类型
# # md5.update(b‘o world‘) # 数据必须是bytes类型
# res = md5.hexdigest()
# print(res) # 5eb63bbbe01eeed093cb22bb8f5acdc3
"""
update无论你是一次性传入还是分批次传入
只要传入的数据是一样的 那么结果肯定一样
"""
"""
123 sdksjdjasljd
132 dsdsadasddsad
hello dsakldjsdjadksad
"""
# 加盐
# import hashlib
# md5 = hashlib.md5()
# md5.update(b‘12321sadsald123kjasdkjal‘)
# md5.update(b‘123‘) # 数据必须是bytes类型
# # md5.update(b‘h‘) # 数据必须是bytes类型
# # md5.update(b‘ell‘) # 数据必须是bytes类型
# # md5.update(b‘o world‘) # 数据必须是bytes类型
# res = md5.hexdigest()
# print(res) # 5eb63bbbe01eeed093cb22bb8f5acdc3
# 动态加盐
# import hashlib
# md5 = hashlib.md5()
# md5.update(b‘‘)
# md5.update(b‘123‘) # 数据必须是bytes类型
# # md5.update(b‘h‘) # 数据必须是bytes类型
# # md5.update(b‘ell‘) # 数据必须是bytes类型
# # md5.update(b‘o world‘) # 数据必须是bytes类型
# res = md5.hexdigest()
# print(res) # 5eb63bbbe01eeed093cb22bb8f5acdc3
日志模块
https://www.cnblogs.com/Dominic-Ji/articles/11109067.html
re模块
"""
正则表达式
通过书写一对看不懂的符号从一大堆文本中
匹配出你想要的内容
它是一门独立的语言
推荐书籍:<<正则指引>>
"""
以上是关于Python函数的主要内容,如果未能解决你的问题,请参考以下文章