python函数“超2万字”的介绍——(带图超详细)

函数

函数是实现特定功能的代码段的封装,在需要的时候可以多次调用函数来实现该功能。

内置函数函数的使用

python内置了许多非常有用的函数,可以直接调用,下面是部分展示。

查看函数的帮助信息

help(名称)
在这里插入图片描述

数学相关

1、绝对值:abs(-1)
2、最大最小值:max([1,2,3])、min([1,2,3])
3、序列长度:len('abc')、len([1,2,3])、len((1,2,3))
4、取模:divmod(5,2)
5、乘方:pow(2,3,4)
6、浮点数:round(1)
在这里插入图片描述

类型转换

1、int(x)
2、str(x)
3、float(x)
4、bool()# 布尔值判断
5、list(x)
6、tuple(x) #元组
7、hex(x)
8、ord(x)#返回字符对应的ASC码数字编号,如ord(‘A’)返回65
9、chr(x)#返回x对应的字符,如chr(65)返回‘A’
在这里插入图片描述
在这里插入图片描述

功能相关

1、函数是否可调用:callable(funcname),注意,funcname变量要定义过(类和类内…),且像整数,字符串,列表,元组,字典等等,都是不可调用的!
2、类型判断:isinstance(x,list/int)
在这里插入图片描述
3、快速生成序列:它的语法:range(start, stop [,step]) ;start 指的是计数起始值,默认是 0;stop 指的是计数结束值,但不包括 stop ;step 是步长,默认为 1,不可以为 0 。range() 方法生成一段左闭右开的整数范围。
必须是整数,可以是负数,但不能是浮点数等其它类型;(3)它是不可变的序列类型,可以进行判断元素、查找元素、切片等操作,但不能修改元素;(4)它是可迭代对象,却不是迭代器。

print(range(5,10))

for x in range(5,10) : # 默认取值
    print(x,end=' ')
print()

for y in range(5,10,2) : # 每隔2个取一次值
    print(y,end=' ')

在这里插入图片描述

自定义函数,参数类型检查

适用于需要多次重复使用相当功能的情况下 定义函数并调用函数。
定义函数语法:
def 函数名(形参1,形参2,…) :
函数体(需实现代码)
调用函数:calc
注意:

  • 函数名可以包含数字、字幕、下划线,但不能以数字开头。
  • 如果函数有返回值,使用 return 关键字
  • 定义函数后函数中的代码并不会执行,需要调用函数才会执行

自定义函数

# 定义参数 使用def关键字
def name(num1,num2) : # 其中num值是必选参数,也成为位置参数,调用的时候必须要有,否则报错
    num = num1 + num2
    return num

#调用
print(name(3,5))

在这里插入图片描述

参数类型检查

# 参数类型检查
def my_abs(x):
    #可以为函数添加文档注释,也称为文档字符串doc string
    # 三个双引号,回车即可自动出现param和return
    """
    计算绝对值
    :param x: 参数
    :return: 返回x的绝对值
    """
    # 对参数类型进行检查
    if not isinstance(x,(int,float)):
        #抛出自定义异常
        raise TypeError('参数类型不正确,只能为数值类型')

    if x>=0:
        return x
    else:
        return -x #绝对值,负负为正
print(my_abs('str'))
print(help(my_abs))
print(my_abs(666))
print(my_abs(-666))

在这里插入图片描述
在这里插入图片描述

默认、可变、关键,命名参数

默认参数

默认参数就是带有默认参数的变量!!
如果我们定义2个值 没有定义默认值的话 如果不赋2个值,就会报错,如果设置默认值以后,那个值即使不定义也不会报错,定义以后就会用你定义的值。
方法:变量=n 即可

# 默认参数
# 计算一个值的n次方
def my_pow(x,y=2): #设置y的默认值为2
    if y==0:
        return 1 #如果输入0,则默认1次方 避免结果为0
    res = x # 定义一个x
    for i in range(y - 1): # 循环次数,因为上面已经定义一个x了,所以这需要-1
        res *= x # 开平方
    return res
print(my_pow(2,3))
print(my_pow(2))

在这里插入图片描述

可选参数

就是说参数可以想传多少传多少,也就是参数数量是可变的。
方法:变量名(*可选参数)或 变量名(固定参数,*可选参数) 注:可选参数是以数组的形式展现,如果要获取里面的值,需要通过遍历获取!

def my_sus(*x): #单独定义一个 可变参数
    print(x)

my_sus(1,2,3,4,5,6) # 以数组方式打印

print('*' * 50)

def my_usu(x,*y): #x是必选参数,y是可选参数
    print(x)
    print(y)
my_usu(1,4,4,4,5,6,7)

在这里插入图片描述

# 也可以调用数组()和[]都可以,方法 *变量名
def my_usu(x,*y): #x是必选参数,y是可选参数
    print(x)
    print(y)
nums=(1,4,4,4,5,6,7)
my_usu(66,*nums) #*nums等同于,nums[0],nums[1],....
print('*' * 50)
my_usu(66,nums)

在这里插入图片描述

如果有必选参数,和 可选参数,建议把必选参数放前面,如果必须参数放后面,需要指定必须变量名再赋值,否则报错

def test(*x,y):
    print(x)
    print(y)
# test(5,4,5,6,412) 这样赋值会报错,会默认为全部是赋值给x的
test(5,13,3,11,y=66)

在这里插入图片描述

关键字参数

使用 ** ,也表示参数个数是可变的,但传递的是带名称的参数。

#关键字参数
def f1(x,**y):
    print(x)
    print(y)

f1(666,a=6,b=66,c='牛牛牛')

在这里插入图片描述

也可以调用字典dict内容,方法和可变参数一样 **变量名

#关键字参数
def f1(x,**y):
    print(x)
    print(y)
# f1(666,a=6,b=66,c='牛牛牛')
user = {'age':23,'name':'ccx','add':'china'}
f1(666,**user)
# 等同于
f1(555,age=user['age'],name=user['name'],add='china')

在这里插入图片描述

命名关键字参数

限制关键字参数的名字,使用* 分割,*号后面的参数表示命名关键字参数。

def f2(x,*,name,age,add): #  *没有任何意义,单纯用来分割而已
    print(name)
    print(age)
    print(add)

f2(666,name='ccx',age=23,add='china')

在这里插入图片描述

接受任意参数

*args:接受任意参数
**kwargs:接受任意命名参数

# 任意参数
def f3(*args,**kwargs):
    print(args)  # 任意参数
    print(kwargs)#任意命名参数

f3(666,555,'ccx','....',age=23,name='ccx',add='china',wa='...')

在这里插入图片描述

自定义函数

空函数

表示先定义一个空函数,以后实现 自定义功能。

def kong() :
    pass  # 表示 是空函数,暂不赋值


# 定义函数的返回值,可以定义多个返回值
def f1():
    name = 'ccx'
    age = 23
    sex = 'man'
    return name,age,sex
print(f1())  # 返回值是一个tuple(数组)
# 获取数组里面的值
a, b, c = f1()  # 任意定义3个参数,按顺序分别对应f1()中的三个参数
print(a, b, c)

在这里插入图片描述

函数的返回值,返回一个函数

简单来说 就是调用一个已定义的函数
方法:直接 函数名() 即可
注:如果用print输出变量名,会多一个None

def test(x) :
    print('你调用了该函数,并输入了参数'+x)

def kong():
    print('你调用了一个空函数')
    pass

test(str(666)) # 调用函数
print(test(str(777)),type(test(str(888)))) #输出函数!!!

print('$' * 50)

kong() #调用函数
print(kong())  # 使用输出结果都会多一个None,而调用却不会!

在这里插入图片描述

也可以嵌套使用,调用的参数或局部变量成为:闭包

def f1(x):
    print('调用了f1')
    y = 6 #定义 局部变量

    def f2(z): #内部函数(这里属于函数f1)
        print(x * y + z) #内部函数使用了外部(f1)函数的参数或局部变量,成为闭包

    return f2 #这里返回属于 内部函数(f2)

fn = f1(3) # 定义变量,并给x赋值3
print('....')
fn(5) # 使用函数,这里定义的其实是z,因为调用f1 返回的是内置函数f2的return

在这里插入图片描述

递归函数

一个函数在内部调用自身,这个函数就叫做递归函数。
demo:计算x的y次方
普通方法

#普通写法
def f1(x,y):
    if y == 0:
        return 1   # 平方次数 最少一次,避免报错
    i = 1
    sum = x
    while i<y : # 因为上面定义了一个sum,所以这需要-1
        sum *= x
        i += 1 #先当于y的+1
    return sum
print(f1(2,0)) #直接调用

ff = f1(2,3) #先定义再返回结果
print(ff)

在这里插入图片描述

递归函数方法

#递归函数方式

def f2(x,y):
    if y==0:  #这里是停止条件,如果不定义这个,就会进入死循环
        return 1
    else:
        #递归条件
        #2x2x2x2x2=2x(2x2x2x2)=2x(2x(2x2x2))=2x(2x(2x(2x2)))=2x(2x(2x(2x(2x1))))) # 这里的1就是停止条件
        return x * f2(x,y - 1) # 不停的调用自己,直到满足y=0停止


print(f2(2,5))

在这里插入图片描述

当然,不能太作死的递归自己,否则会栈溢出!
在这里插入图片描述

变量作用域和命名空间

变量作用域

变量作用域 scope:指的是变量生效的区域
有两种作用域:
1,全局作用域:函数意外的区域都是全局作用域,在全局作用域中定义的变量,都是全局变量。
2,函数作用域,也称为局部作用域:函数内的区域,每调用一次函数就会创建一个新的函数作用域,在函数作用域中定义的变量,都是局部变量。
变量的查找顺序:先在当前作用域中查找,如果没有则向上一级作用域中查找,直到查找全局作用域,如果还是没有,则报错。

#作用域介绍
a = 666 #全局变量

if True:
    b = 777 #全局变量(不在函数内!!!)
    # 在python中没有块级作用域(在java中 这里面定义的外面是用不了的)

def f1():
    c = 999 #局部变量
    print('函数内部:a=',a)
    print('函数内部:b=', b)
    print('函数内部:c=',c)

f1()
print('——' * 20)
print('函数外部:a=', a)
print('函数外部:b=', b)
# print('函数外部:c=', c)

在这里插入图片描述

默认全局变量中的变量名与局部(函数内)变量名没有关系。

a = 10 #全局a
def fn():
    a=20 #局部a
    print('内部a',a)
print('外部a',a)
fn()
print('——' * 20)
global关键字(局部中让外部生效)
b = 10
def fn2():
    #如果想在内部函数中修改全局变量的值,需要使用参数 global关键字来声音变量
    global b # 声明这里面的b是全局变量b
    b = 20
    print('内部b',b)
    return b
fn2()
print('外部b',b)

在这里插入图片描述

#变量查找介绍
#先在当前作用域中查找,如果没有则向上一级作用域中查找,直到查找全局作用域,如果还是没有,则报错。
x = 1#全局作用域
def f2():
    x = 2#上一级作用域
    print(x)
    def f3():
        x = 3#当前作用域
        print(x)

命名空间

命名空间namespace:指的是变量存储的位置,每一个变量都要存储在指定的命名空间中;
每个作用域都有一个对应的命名空间;
全局命名空间,用来存储全局变量;
函数命名空间,用来存储函数中的变量;
命名空间实际上就是一个字典(dict),是一个专门用来存储变量的字典。

获取命名(locals)

使用方法: locals() 获取当前作用域的命名空间
注:在全局中使用就是调用全局命名,在函数中使用并调用函数,就是获取该函数中的命名。

# 命名空间
a = 6
b = 66

scp = locals()
print('全局变量:',scp)
print('参数类型:',type(scp)) # 在全局作用域中调用locals,获取的就是全局命名空间

def f1():
    c = 666
    print('调用函数:',locals())
f1()

def f2(name) : #设置返回值
    age = 23
    sc = locals()
    print('调用参数函数命名:',sc) #返回一个名字/值对的字典
f2('ccx') #调用并输入返回值

在这里插入图片描述

修改命名参数

a = 6
b = 7
print('修改前的总变量:',a,b)
scp = locals()
scp['a'] = 666 # 修改变量a
scp['b'] = 777
print(scp)
print('修改后的总变量:',a,b)

z = 456
def f1():
    c = 123
    sc = locals()
    sc['c'] = 321
    sc['z'] = 654 #修改总变量z ,因为查找规则就是先函数后总变量,但仅对当前函数生效
    print(sc)
    print('函数中修改总变量:',z) # 函数中修改的总变量,不能直接用print打印!
f1()
print('总变量z:',z)

在这里插入图片描述

获取命名(globals)

可以在任意位置获取全局命名空间
方法:globals()

a = 6
def f1():
    b = 7
    scp = globals()
    print(scp)
    print(scp['a'])
f1()

在这里插入图片描述

高级特性(迭代和列表生成式)

迭代

迭代:迭代的意思是重复做一些事很多次,就像在循环中做的那样,也称为遍历,循环获取每一个元素;

  • 回忆一下普通遍历:
for i in ('tom','alk','ccx') :
    print(i,end=',')
print()
for j in {'name':'ccx' , 'age':'2','ccx':'最帅'}.keys():
    print('1:',j,end=',')
print()
for j in {'name':'ccx' , 'age':'2','ccx':'最帅'}.items():
    print('2:',j,end=',')
print()
for k,l in {'name':'ccx','age':22,'ccx':'超级cool'}.items() :
    print('3:',k,l,end=',')
print()
print('4:',end=' ')
for n in 'good evening' :
    print(n,end=',')

在这里插入图片描述

  • 判断是否可迭代
    需要判断对象是否是可迭代的,判断方法:isinstance(file,Collections,Iterable) ——返回布尔类型
print(isinstance('good evening',Collections,Iterable))
  • 使用enumerate()函数,转换为索引-元素对
name = {'ccx':'is a hero','age':22}
print(enumerate(name))
print('enumetate函数:',end=' ')
for k,v in enumerate(name):
    print(k,v,end=',')
print()
print('普通遍历:',end=' ')
name1 = {'ccx':'is a hero','age':22}
for n,m in name1.items() :
    print(n,m,end=',')
 

在这里插入图片描述

  • 迭代使用
    迭代器是一个可以记住遍历的位置的对象。
    迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
    迭代器有两个基本的方法:iter()next()
    迭代器iterator:用来访问集合元素的一种方式,可以记住迭代的位置。
    字符串,列表或元组对象都可用于创建迭代器

迭代的普通用法

# 普通迭代 一次一个值
list = [1,2,3,4]
i = iter(list) #调用iter()函数创建迭代器
print(next(i))# 调用next()函数获取迭代器的下一个元素
print(next(i))
print(next(i))
print(next(i))

迭代器对象可以使用常规for语句进行遍历:
和普通遍历比起来,区别最大的可能就是 逼格更高把??? 或许迭代器只能往前不会后退。虽然知道怎么体现,但看不见的好处或许就是这个把!!!
在这里插入图片描述

next使用:因为的我会报错,所以我加了个try机制。没找到原因。

list = [1,2,3,4]
i = iter(list)
while True:
    try:
        print(next(i))
    except StopIteration:
        exit()

列表生成式

列表生成式:简单来说,用来创建list的生成式
如: 生成0-99的list

# 普通for循环的方法
for i in range(0,100):
    print(i,end=',')
print()

#生成式方法
nums = range(0,100)# 如果转换格式 其实就是个range模式。
print(nums)
print()

nums1 = list(range(0,100)) # 需要转换为list格式,可以直接打印!!!!
print(nums1,end=',')

在这里插入图片描述

如:打印1,100之间所有的偶数
在这里插入图片描述
如:生成一个包含1-100之间所有3的倍数的list

# 方式一
print('方法一:',end=' ')
lst = range(1,101)
for i in lst:
    if i % 3 == 0:
        print(i,end=',')
print()

# 方式二
print('方法二:',end=' ')
lst1 = []
for i in range(1,101):
    if i%3 == 0 :
        print(i,end=',')
print()

#方式三
print('方法三:',end=' ')
lst2 = [i for i in range(1,101) if i%3==0]
print(lst2)

在这里插入图片描述

生成器

生成器generator:在循环过程中一次计算获取值的对象;
创建生成器的方式:
方式一:把一个列表生成式的[]改成()

#方式一:把一个列表生成式的[]改成()
generator = (i for i in range(0,100))
print('generator类型为:',type(generator))
# 注意,上面的generator并没有生成值,只有获取时才会生成值

# 获取生成器的下一个值
print(next(generator))
print(next(generator))
print(next(generator))
print(next(generator))
print('*' * 50)

# 遍历generator的值
for i in generator:
    print(i,end=',') # 因为0-3上面已经用next获取了,所以这儿不会有0-3

在这里插入图片描述

知道迭代特性会记录获取的值,所以如果提取超过值便会抛异常
在这里插入图片描述
方式二:在函数中使用yield关键字,此时该函数就变成一个生成器函数

#方式二:在函数中使用yield关键字,此时该函数就变成一个生成器函数
def gen():
    print('one')
    yield 13
    print('two')
    yield 8
    print('three')
    yield 25
    print('four')
    yield 38

#生成器函数与普通函数的执行流程不一样;
#普通函数是顺序执行,执行到最后一行或者遇到return时结束
#生成器函数是在每次嗲用next时执行,遇到yield语句就返回,下一次调用next()时会从上一次返回的yield语句处继续执行
g = gen()
print(type(g))
print(next(g))
print(next(g))
print(next(g))

print('*' * 50)

#使用for循环遍历生成器
for i in g:
    print(i) #从上一个next()返回结果的下一处继续执行!

在这里插入图片描述

高阶函数

自定义高阶函数

高阶函数:一个函数接收另一个函数作为参数,这种函数成为高阶函数。

# 定义一个函数,用来检查数字是否大于5
list = [4,5,6,7,8,18, 19, 20, 21, 22, 23, 24,111,112]
def f1(x):
    if x > 5:
        return True #没有实际作用,只是测试满足x>5就会输出True而已
    return False
print('f1条件函数:',f1(6))
print('*' * 59)

#自定义高阶函数,用来过滤列表中的函数
def f2(fun,list):
    """
    将列表中所有符合条件的元素筛选出来,返回一个新列表
    :param fun: 条件函数
    :param list: 要进行筛选的列表
    :return: 返回新列表
    """
    new_list=[] # 创建一个新列表
    for i in list:
        if fun(i):
            new_list.append(i) #满足条件的添加到列表中
    return new_list # 返回新列表
num = f2(f1,list) # 调用f1函数,传入list列表内容
print('f2条件函数:',num)
print('*' * 50)

在这里插入图片描述

定义这种高阶函数的好处在于 条件可以随时变更 ,然后调用高阶函数的时候再调用新的条件函数即可,如:上面创建了一个>5的条件函数(f1),一个高阶函数(f2),现在创建一个新的条件(f3)

#自定义高阶函数,用来过滤列表中的函数
def f2(fun,list):
    """
    将列表中所有符合条件的元素筛选出来,返回一个新列表
    :param fun: 条件函数
    :param list: 要进行筛选的列表
    :return: 返回新列表
    """
    new_list=[] # 创建一个新列表
    for i in list:
        if fun(i):
            new_list.append(i) #满足条件的添加到列表中
    return new_list # 返回新列表
num = f2(f1,list) # 调用f1函数,传入list列表内容
print('f2条件函数:',num)
print('*' * 50)

def f3(x):
    if x % 2 == 0: # 只要偶数
        return True
print('f3条件函数:',f2(f3,list)) #输出并调用 f2高阶函数,传入 函数f3和list列表

在这里插入图片描述

内置高阶函数

  • 内置高阶函数 filter(),用于过滤序列
    使用方法:filter(条件函数,列表)
lst = [4,5,6,7,8,18, 19, 20, 21, 22, 23, 24,111,112]
def f3(x):
    if x % 2 == 0: # 只要偶数
        return True

num = filter(f3,lst)
print(list(num))

在这里插入图片描述

  • 内置高阶函数 map(),用于处理序列
    使用方法:map(条件函数,列表)
lst = [4,5,6,7,8,18, 19, 20, 21, 22, 23, 24,111,112]
def f4(n):
    return n+1
def f5(n):
    return n*n

print('原列表:',lst)
print('所有数值+1:',list(map(f4,lst)))
print('所有数值开平方:',list(map(f5,lst)))

在这里插入图片描述

  • 内置高阶函数 sorted(),用于排序
    使用方法:sorted(列表) # 默认排序 小到大
    sorted(列表,reverse=True)# 大到小排序
    sorted(列表,key=)#key= 是自定义条件,后面也可以加reverse=True
lst = [1,2,3,-55,-100,66] #普通列表
lst1 = [{'a':1,'b':2,'c':3,'d':4}] #多维列表
a = sorted(lst) # 默认排序 从小到大
b = sorted(lst,reverse=True) #从大到小,因为reverse默认为false。
c = sorted(lst,key=abs,reverse=True) #最简单的条件,绝对值排序
d = sorted(lst1,key=lambda n:n,reverse=True)
# d是多维列表的使用方法,按理说 n:n[0]是单独提取不排序,n:n[1]是排序,但我这会报错,不知道为啥。n是自定义的。
print('小到大:',a)
print('大到小:',b)
print('绝对值(大到小):',c)
print(d)

在这里插入图片描述

匿名函数和装饰器

匿名函数

匿名函数:没有名字的函数,只能使用一次。 
方法:lambda关键字
nums = [3,55,6,22,8]

# 以map为例,让nums列表中值 x2+1
def f1(x):
    return x*2+1
a = list(map(f1,nums))
print('f1函数返回结果:',a)

# 假设f1函数只用一次,这么定义一个f1 就显得有点麻烦了,所以可以定义一个 匿名函数
b = list(map(lambda x:x*2+1,nums))

	print('匿名函数返回值:',b)

在这里插入图片描述

匿名函数除了可以调用列表以外,也可以定义一个匿名函数,然后赋值并调用匿名函数

abc = lambda x:x+5
print(abc(1))
print(abc(555))

在这里插入图片描述

装饰器

装饰器:装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能(称为装饰器Decoration,类似于AOP),装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
方法:先定义一个装饰器(其实就 是一个 def函数)

def name():
    def new_name():
        #功能块
    return new_name()

使用:在 需要增加功能的函数上面 @装饰器函数name即可

如:

# 定义一个装饰器,为该函数添加打印日志功能
def log(fn):
    def wrapper(*args,**kwargs):
        print('开始执行%s()函数。。。'% fn.__name__) # __name__ 内置属性,获取名字
        res = fn(*args,**kwargs)
        print('执行%s()函数结束。。。' % fn.__name__)
    return wrapper()  #返回装饰函数
# 随便定义了一个装饰器def abc(a):
    def c():
        print('this is ...')
    return c()

lst = [ 2,3,4,5,6,66,555]

@log
def f1(lst):
    for i in lst: #遍历
        if i % 2 ==0 : #只要偶数
            print(i)

@abc
def f2(num1,num2):
    sum = num1+num2 # 计算
    return sum # 返回sum

f1(lst)
print('*' * 50)
print(f2(3,5))

注:上面代码运行有报错,方法就是这样使用的,至于为什么运行报错, 现在的我并无法解决,报错如下。
在这里插入图片描述

那时的我无法解决,不代表现在的我无法解决(我的博客都是累计到一定数量,然后一并发布)。既然不会 那么就多查资料 多总结多实验嘛 ,单独说下 修饰器,参见:https://blog.csdn.net/cuichongxin/article/details/106563876

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章