python not函数_python 函数
本站寻求有缘人接手,详细了解请联系站长QQ1493399855
1 为什么使用函数
在没有接触函数时,有时候需要将一个功能多次写,如果需要修改其中一个变量,则需要把所有实现该功能的代码一处一处改。不利于代码维护,代码量大了,组织结构也会很不清晰。
所以总结不使用函数的确定:
代码冗余(重复代码多)
不利于维护(修改麻烦)
可读性差(组织结构不清晰)
函数的优点:
解决代码重用问题
统一维护
程序的组织结构清晰,可读性强
# 2 函数的定义
函数种类:
内置函数:内置在python解释器的函数
自定义函数:
def funtion_name(args):
"""描述信息""" #可通过function_name.__doc__查看
函数主体
return
自定义函数的种类
空函数
def abc():
"""描述信息"""
pass
空函数使用在布置程序大致框架时,不用具体实现函数的功能。
有参函数
def abc(args):
return xxx
通常有参的函数,都是有返回值的。
无参函数
# 3 函数调用
语句形式:函数名()
表达式形式:res=10*abc(1)
函数调用作为另一个函数的参数:print(abc())
注意:我们调用一个不存在的函数
```python
func() #NameError: name 'func' is not defined
#a=b #NameError: name 'b' is not defined
```
这里返回的是,“NameError”,函数名未定义。所以,在python中,我们可以理解为**定义函数,就是定义变量名**。
# 4 函数的返回值
python中函数的返回值可以是任意类型。
1. 没有return或return为空,返回的是None。
2. 可以返回多个函数值(本质是打包成一个元组)
3. 如果有多个return(语法上不会报错),但返回第一个遇到的return。
注意:
def my_min(x:int,y:int) ->int:
print(my_min.__annotations__) #{'x': , 'y': , 'return': }
该方法适合那些从c++,java转到Python的。
# 5 函数的参数
定义函数时的参数,就是形式参数。
调用函数时的参数,就是实际参数。
函数调用时,会把实参绑定到形参,结束调用时,解除绑定。
#形参、实参都是不可变
def foo1(a):
a=3
print(a)
x=1
foo1(x) #3
print(x) #1
foo1里面重新给a赋值不会影响x,为什么?我们可以这样理解,实参是本身存的一个变量的值,而形参存的是一个变量名(没有值)。当发起函数调用时,形参会绑定实参的值,如果在函数内给形参赋值,形参会绑定新的值。(可以和变量与变量的赋值类比)所以不会改变实参的值。
#形参是可变类型
def foo2(a,L=[]):
L.append(a)
print(L)
foo2(1) #[1]
foo2(2) #[1, 2]
foo2(3) #[1, 2, 3]
当foo2加载到内存,L指向的是[],当每一次调用函数时,都是在向同一个[]附加数据。
#改良版
def foo2(a,L=None):
if L is None:
L=[]
foo2(2) #[2]
foo2(3) #[3]
#实参是可变类型
def foo3 (L):
L.append("abc")
print("foo",L)
li=[1,2,3]
foo3(li)
print(li) #[1, 2, 3, 'abc']
当把一个列表li当实参传到函数时,是将列表li的地址传给形参,所以形参所做的修改,都会影响实参。建议:不要使用可变对象作为实参。
a=1
def foo3(x=a):
print(x)
foo3() #1
这里要区别于java等编译型语言。python作为一门解释型语言,是一边解释一边执行的。当它执行到foo3(),形参x=1被写入内存的。当执行到a=3时,并不会影响x的值。
6 函数的实参
def func(a,b,c)
实参传值的方式:
按位置传参:func(1,2,3)
按关键字传值:func(a=1,b=2,c=3)
混合传值:func(a=1,b=2,c=3)
混合传值注意事项:
按位置传值必须在按关键字传值之前
一个形参只能接收一个传值,如:func(1,2,b=2)会报错,此时b接收了2个值
7 函数的形参
位置参数:必须传值
默认参数:可传可不传,且必须放位置参数后面
func(a,b=2)
可变参数 *args 可以理解为一堆位置参数
先按位置传值,剩下的被*接收,打包成一个元组,再传给args#从形参的角度,形参带*
def func(a,b,*args)
func(1,2,3,4,5,6)
result:
b=2
args=(3,4,5,6)
#从实参的角度,实参带*
def foo1(x,y,z):
print(y)
print(z)
foo1(*(1,2,3)) #如果去掉*,会把整个元组赋值给x,此时y和z没有值会报错
当实参遇到*(1,2,3),需要把它拆成1,2,3这样来看
关键字传值 **kwargs 按关键字传值多余的被**接收,打包成一个字典,传给kwargs
#从形参的角度,形参带**
def foo2(**kwargs):
print(kwargs)
foo2(a="aa",b="bb")
#从实参的角度,实参带**
def foo3(x,y,z=1):
foo3(**{"x":"a","y":"b"})
命名关键字 *,args 用于指定必须以某些关键字来传值
def foo4(*,x,y=2):
foo4(x=1)
命名关键字参数不能和可变参数混用
形参的顺序:
def func1(a,b=2,*args,**kwargs)
def func2(a,b=2,*,c=3,**kwargs)
8 nonlocal
nonlocal关键字,只在python3才有。
nonlocal 的作用就是将变量添加到上一层函数的局部命名空间中。
def layer_1():
count=1
def layer_2():
count=2
def layer_3():
nonlocal count
count=3
print(count)
print(locals())
layer_3()
layer_2()
layer_1()
结果:
3
{'count': 3}
{'layer_3': .layer_2..layer_3 at 0x000002B39BF7BB70>, 'count': 3}
1
{'layer_2': .layer_2 at 0x000002B39BF7BAE8>, 'count': 1}
在第3层定义的nonlocal count,count=3影响到第2层count的结果,但第1层没有任何影响