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函数的主要内容,如果未能解决你的问题,请参考以下文章

python使用上下文对代码片段进行计时,非装饰器

python 元组有用的函数,方法和片段。

Python代码阅读(第26篇):将列表映射成字典

VSCode自定义代码片段——声明函数

Python学习 :函数

VSCode自定义代码片段8——声明函数