函数(2)
文章目录
不定长参数
函数中,在定义形参的时候可以在形参的前面加上*或者**
*形参和**形参的相同点
- 都能够接收多个传递过来的实参
- 在函数中只能定义一个
不同点:
*形参:
- 保存的数据类型是元组
# def fn(*args):
# r = 0
# print(args,type(args))
# for i in args:
# r += i
# return r
# r = fn(4,3,4,56,3)
# print(r)
# (4, 3, 4, 56, 3) <class 'tuple'>
# 70
- 只能接收位置传参,不能接收关键字传参
# def fn(x,y,*z):
# print('x =',x)
# print('y =',y)
# print('z =',z)
#
# fn(1,2,3,4)
# x = 1
# y = 2
# z = (3, 4)
# fn(1,2,z=3)
# TypeError: fn() got an unexpected keyword argument 'z'
- 如果*形参后面还有形参,后面那个形参只能用关键字传参
# def fn(x,*y,z):
# print('x =',x)
# print('y =',y)
# print('z =',z)
#
# fn(1,2,3,4)
# TypeError: fn() missing 1 required keyword-only argument: 'z'
# 如果*形参后面还有形参,则后面的形参需要使用关键字传参
# fn(1,2,3,z=4)
# x = 1
# y = (2, 3)
# z = 4
**形参:
- 保存的数据类型是字典
# def fn(**kwargs):
# print(kwargs,type(kwargs))
# for k,v in kwargs.items():
# print(k,v)
# fn(a=1,b=2,c=3)
# {'a': 1, 'b': 2, 'c': 3} <class 'dict'>
- **形参只能在所有形参的最后
# def fn(**kwargs,a):
# print(kwargs,a)
# SyntaxError: invalid syntax
- 只接收关键字传参,不接收位置传参
# def fn(**kwargs):
# print(kwargs,type(kwargs))
# fn(1,2,3,4)
# TypeError: fn() takes 0 positional arguments but 4 were given
# fn(a=1,b=2,c=3)
# {'a': 1, 'b': 2, 'c': 3} <class 'dict'>
参数的解包
- 传递实参时,可以在序列类型的实参前面加一个*或者**,这样可以把序列里面的元素依次赋值给形参
- 要求序列中的元素个数和形参个数相同
# 参数亦可以通过解包来传递参数
# def fn(x,y,z):
# print(x,y,z)
# t = (1,2,3)
# t = (1,2,3,4)
# TypeError: fn() takes 3 positional arguments but 4 were given
# 要解包的元组元素个数要与形参个数相同
# fn(*t)
# 1 2 3
# d = {'x':1,'y':2,'z':3}
# d = {'x':1,'y':2,'a':3}
# TypeError: fn() got an unexpected keyword argument 'a'
# 要解包的字典的键的名称要与形参的名称相同
# fn(**d)
# 1 2 3
函数的返回值
函数的返回值指的是函数执行以后返回的结果
函数中用return来指定函数的返回值,可以用一个变量来获取函数的返回值
# def fn(*args):
# r = 0
# for i in args:
# r += i
# return r
# r = fn(1,2,3) # 可以用一个变量来接收返回值
# print(r)
# print(fn(1,2,3)) # 也可以直接打印返回值
return后面跟的可以是任何对象,包括函数对象
# def fn():
# return (1,2,3)
# print(fn(),type(fn()))
# 返回值可以是元组
# def fn():
# return [1,2,3]
# print(fn(),type(fn()))
# 返回值可以说是列表
# def fn():
# return fn2
#
# def fn2():
# return 1
# print(fn(),type(fn()))
# r = fn()
# print(r())
# 返回值还可以是函数
如果函数中没有return,或者仅仅只有return,则该函数的返回值为None
# def fn():
# return
# print(fn())
# None
# def fn():
# a = 10
# print(fn())
# None
return可以用于结束函数,函数中一执行return语句,函数自动结束;return后面的语句都不执行
# def fn():
# for i in range(5):
# if i==3:
# break
# print(i)
# print('循环结束')
# fn()
# 3
# 循环结束
# def fn():
# for i in range(5):
# if i==3:
# return i
# print(i)
# print('循环结束')
# r = fn()
# print(r)
# 3
文档字符串
help()
help():可以查询函数的使用方法
语法:help(函数对象)
# help(print)
# print(...)
# print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
# Prints the values to a stream, or to sys.stdout by default.
# Optional keyword arguments:
# file: a file-like object (stream); defaults to the current sys.stdout.
# sep: string inserted between values, default a space.
# end: string appended after the last value, default a newline.
# flush: whether to forcibly flush the stream.
help()和文档字符串的搭配使用
# def fn(x:int,y:int,z:int)->int:
# '''
# 功能:......
# 参数:......
# :param x:类型,默认值,作用
# :param y:类型,默认值,作用
# :param z: 类型,默认值,作用
# :return: 返回值
# '''
# return 1
#
# help(fn)
函数的作用域
作用域是指变量生效的区域
作用域在Python中分为两种:
全局作用域
- 全局作用域在程序运行时创建,在程序结束时被销毁
- 所有函数以外的区域就是全局作用域
- 在全局作用域定义的变量是全局变量,可以在任意位置访问
函数作用域
- 函数作用域在调用函数时创建,在函数结束运行时被销毁
- 函数每一次被调用都新创建一个函数作用域
- 在函数作用域定义的变量时局部变量,只能在函数内部被访问
- 如果在函数作用域要修改全局变量,需要用global声明该全局变量,然后才能在函数内修改
# 全局变量
a = 10
b = 20
# def fn():
# c = 10 # 局部变量
# print(a+c)
#
# fn()
# print(c) # NameError: name 'c' is not defined
# 在全局访问不了局部变量
# def fn():
# a = 20
# print('函数内部的a:',a)
# fn()
# print('函数外部的a:',a)
# 函数内部的a: 20
# 函数外部的a: 10
# 全局作用域和函数作用域的变量尽管名称一样,但其在内存的地址不同
# 如果在函数内对全局变量进行修改,需要用到global()
# def fn():
# global a
# a = 20
# print('函数内部的a:',a)
# fn()
# print('函数外部的a:',a)
命名空间
命名空间的用处不大
命名空间是一个字典,用来存放变量的字典
locals()
locals()可以获取当前作用域的命名空间
如果在全局作用域执行locals(),则获取全局作用域的命名空间
如果在函数作用域执行locals(),则获取函数作用域的命名空间
locals()的返回值是字典
如果想在函数作用域内获取全局作用域的命名空间,则须用globals()
# a = 10
# b = 20
# print(locals())
# def fn():
# c = 10
# d = 20
# print(locals())
# print(globals())
# fn()
递归函数
递归
递归是一种解决问题的方式
整体思想是将一个问题细化成小问题,再把小问题细化为更小的问题,直到问题无法再被细化,再去解决问题
递归简单来说就是自己调用自己
递归函数就是在函数内自己调用自己
递归函数有两个条件
- 基线条件:将问题不断细化,当满足基线条件时,不再进行递归
- 递归条件:将问题继续细化的条件
递归函数的例子
任意数的阶乘
# 用递归的方式解决任意数的阶乘
# 10!=10*9!,9!=9*8! => 10!=10*(10-1)!,.......
# def fn(n):
#
# if n == 1: # 基线条件,满足该条件就不再递归
# return 1
#
# return n * fn(n-1)
#
# print(fn(10))
任意数的任意幂运算
# 定义一个函数,来为任意数字做任意幂运算
# 任意数字的任意幂运算:n**i,n和i都为用户输入的数字
# n**i = i个n相乘,即当i==1时,不用再继续往下乘以n
# 基线条件:i==1;递归条件:n*n
# def fn(n,i):
#
# if i == 1:
# return n
#
# return n * fn(n,i-1)
#
# print(fn(5,3))
判断回文
回⽂字符串从前往后念和从后往前念是⼀样的。例如 TNT
# 方法一
# def fn(args,i):
#
# if i == int(len(args)/2):
# return True
#
# if args[i] != args[len(args)-1-i]:
# return False
# else:
# return fn(args,i+1)
#
# str = input('please input a string:')
#
# if len(str) < 3:
# print('你输入的数据有误,至少输入三个字母')
# else:
# r = fn(str,0)
# print(r)
# 方法二
# def fn(str):
#
# if len(str) < 2:
# return True
#
# elif str[0] != str[-1]:
# return False
#
# return fn(str[1:-1])
#
# str = input('please input a string:')
# r = fn(str)
# print(r)
以上内容为个人总结+资料查找,欢迎批评指正