Python函数

如果一个函数想返回两个结果怎么办?可以用两个return去实现吗?
不可以
但是可以一个return返回两个结果,这个是python的特性,java,C++就不能这样返回,只能将返回参数封装后进行返回,C++可以使用tuple返回多个,具体百度查一下

def return_num():
return 1,2
result = return_num()
print(result) # (1,2)

注意

  1. return a,b 写法,返回多个数据的时候,默认是元组类型。
  2. return后面可以连续列表,元组或者字典,以返回多个值。

1.函数参数

#s:str代表参数s是str类型,就是参数的声明,方便调用str的方法,但是调用函数时,传别的类型也不一定会报错,并不是强制的。
#->str代表返回类型是str
def test(s:str)->str
	pass

1.1位置参数(常用)

位置参数:调用函数的时候根据函数定义的参数位置来传递参数
注意:传递和定义参数的顺序及个数必须一致

def user_info(name,age,gender):
print(f'您的名字是{name},年龄是{age},性别是{gender}')
user_info('bull',20,'男')

1.2关键字参数

关键字参数: 函数调用,通过’键=值‘形式加以指定。可以让函数更加清晰,容易使用,同时也清楚了参数的顺序需求。
注意: 函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序。

def user_info(name,age,gender):
print(f'您的名字是{name},年龄是{age},性别是{gender}')
# 调用函数
user_info('bull',age=20,gender='男') #位置参数要放在关键字参数的后面,关键字参数不要求顺
序,无所谓
user_info('bull',gender='男',age=20)

1.3缺省参数

缺省参数:缺省参数也叫默认参数,用于定义函数,为参数提供默值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)
注意:函数调用时,如果为缺省参数传值则修改默认参数值;否则使用这个默认值

def user_info(name,age,gender='男'):
print(f'您的名字是{name},年龄是{age},性别是{gender}')
# 调用函数,使用默认参数,不传gender
user_info('bull',18)
# 调用函数,更改默认的参数值
user_info('tom',age=23,gender='男')
# 调用函数,关键字参数不区分顺序,只要在位置参数后面就可以
user_info('jack',gender='男',age=25)

1.4不定长参数

不定长参数:也可叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得非常方便。

  1. 位置参数传递
    注意:传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是包裹位置传递。
def user_info(*args):
print(args)
user_info('TOM') # ('TOM',)
user_info() # ()
user_info('tom',90) # ('tom', 90)
  1. 关键字参数传递
    kwargs会被视为一个字典
def user_info(**kwargs):
print(kwargs)
# 返回的结果是{'name': 'tom', 'age': 10, 'gender': '男'}
user_info(name='tom', age=10, gender='男')

1.5强制命名参数

在带星号的“可变参数”后面增加新的参数,必须在调用的时候“强制命名参数”。

def f1(*a,b,c):
    print(a,b,c)
#f1(2,3,4)   #会报错。由于a是可变参数,将2,3,4全部收集。造成b和c没有赋值。
f1(2,b=3,c=4)
#执行结果:(2,) 3 4

2.参数传递

函数的参数传递本质上就是:从实参到形参的赋值操作。Python中“一切皆对象”,所有的赋值操作都是“引用的赋值”。所以,Python中参数的传递都是“引用传递”,不是“值传递”。
具体操作时分为两类:
1 对“可变对象”进行“写操作”,直接作用于原对象本身。
2 对“不可变对象”进行“写操作”,会产生一个新的“对象空间”,并用新的值填充这块空间。
数字是不可变对象

2.1传递可变对象的引用

传递参数是可变对象(例如:列表、字典、自定义的其他可变对象等),实际传递的还是对象的引用。在函数体中不创建新的对象拷贝,而是可以直接修改所传递的对象。

2.2传递不可变对象的引用

传递参数是不可变对象(例如: int 、 float 、字符串、元组、布尔值),实际传递的还是对象的引用。在”赋值操作”时,由于不可变对象无法修改,系统会新创建一个对象

2.3传递不可变对象包含的子对象是可变的情况

不可变对象里面包含的子对象是可变的。如果在方法内修改了这个可变对象,那么源对象也会发生变化。

a = (10,20,[5,6])
print("a:",id(a))
def test01(m):
    print("m:",id(m))
    m[2][0] = 888
    print(m)
    print("m:",id(m))
test01(a)
print(a)
#执行结果:
#a: 41611632
#m: 41611632
#(10, 20, [888, 6])
#m: 41611632
#(10, 20, [888, 6])

3.lambda表达式

语法:lambda 参数 :表达式
注意
lambda表达式的参数可有可无,函数的参数在lambda表达式中完全适用
lambda函数能接收任何数量的参数但只能返回一个表达式的值
示例:

add = lambda x, y: x + y
print(add(3, 5))  # 输出:8

4.内置函数

4.1 map()

map() 会根据提供的函数对指定序列做映射。
语法

map(function,iterable,....)
参数:
function:函数
iterable:一个或多个序列
返回值:python3返回的是迭代器

第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回
值的新列表。如果要转换为列表,可以使用list()来转换。
示例:计算 list1 序列中各个数字的2次方

list1 = [10,20,30,3]
result = map(lambda x:x**2,list1)
print(result) #<map object at 0x01942130> 如果想要得到列表要用list()去做处理
new_list = list(result)
print(new_list) #[100, 400, 900, 9]

4.2 reduce()

reduce( func(x,y) , lst ) 函数会对参数序列中元素进行累积。 其中 func 必须有两个参数。每次
func 计算的结果继续和序列的下一个元素做累积计算
注意

  1. reduce()传入的参数 func 必须接收2个参数。
  2. reduce是要从 functools 里面去导包的
    示例:计算 list1 序列中各个数字的累加和
from functools import reduce
list1 =[1,2,3,4,5]
result = reduce(lambda x,y:x+y,list1)
print(result) # 15

4.3filter()

filter( func , lst )函数用于过滤序列,过滤掉不符合条件的元素,返回一个filter对象。如果要转换为列
表,可以使用list()来转换。
示例:筛选出列表里面的偶数项

list1 = [1,2,3,4,5,6,7,8,9,10]
def func(x):
return x%2 == 0
result = filter(func,list1)
print(result) #<filter object at 0x02BA2130>
print(list(result)) # [2, 4, 6, 8, 10]

4.4eval()函数

功能:将字符串 str 当成有效的表达式来求值并返回计算结果
⚠️eval函数 会将字符串当做语句来执行,因此会被注入安全隐患。比如:字符串中含有删除文件的语句。那就麻烦大了。因此,使用时候,要慎重!!!
语法: eval(source[, globals[, locals]]) -> value
source :一个Python表达式或函数 compile() 返回的代码对象 1
globals :可选。必须是 dictionary 2
locals :可选。任意映射对象 3

#测试eval()函数
s = "print('abcde')"
eval(s)#把s当作代码执行,执行结果:abcde
a = 10
b = 20
c = eval("a+b")
print(c)#执行结果30
dict1 = dict(a=100,b=200)
d = eval("a+b",dict1)#表示这里的a和b是使用dict1里面的a和b,而不是全部的a和b
print(d)#执行结果:300

在函数内部,如果只是使用全局变量,则无需使用global声明,如果需要修改,则需要

5.内存分析

函数也是对象,函数名存放的是函数的地址
Python中,圆括号意味着调用函数。在没有圆括号的情况下,Python会把函数当做普通对象。

def print_star(n):                
    print("*"*n)
print(print_star)
print(id(print_star))
c = print_star
c(3)

代码执行 def 时,系统中会创建函数对象,并通过print_star这个变量进行引用:
在这里插入图片描述
执行 c=print_star 后,显然将 print_star 变量的值赋给了变量 c ,内存图变成了:
在这里插入图片描述

6.嵌套函数(内部函数)

嵌套函数:在函数内部定义的函数!

def  outer():
    print('outer running...')
    def inner():
        print('inner running...')
    inner()
outer()
#执行结果:
#outer running...
#inner running...

inner() 就是定义在 outer() 函数内部的函数。 inner() 的定义和调用都在 outer() 函数内部

7.nonlocal关键字

nonlocal 用来在嵌套函数中,声明外层的局部变量。

#测试nonlocal、global关键字的用法
a = 100
def outer():
   b = 10
   def inner():
       nonlocal  b         #声明外部函数的局部变量
       print("inner b:",b)
       b = 20
       global a            #声明全局变量
       a = 1000
    inner()
    print("outer b:",b)
outer()
print("a:",a)
#执行结果:
#inner b:10
#outer b:20
#a:1000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力码代码的小赵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值