python之路(函数)

函数:封装一个功能,减少代码的重复率,增强可读性,函数中尽量不要出现print

def(#函数标识) my_len(#函数名)()(#内置参数,可设可不设,看需要):

l = [1, 2, 3, 4]
count = 0
  for i in l:
  count += 1
return count#函数的返回值
print(my_len())#函数的执行者

result:4

函数的返回值 return

# 1,函数中如果遇到retrun,则直接结束函数。
# 2,给函数的执行者返回值。

# return None
# return 单个值 原封不动的返回,是什么类型就返回什么类型
# return 多个值 一个元组,所有的返回值作为元组的每一个元素

def func1():
print(111)
print(222)
return
print(333)
print(func1()) # 整体是函数的执行者。

result:

111
222
None

def func1():
a = 1
b = 2
c = a + b
d = 'alex'
e = [1,2,3]
return c,d,e
ret = func1()
print(ret,type(ret)) # 整体是函数的执行者。

result:(3, 'alex', [1, 2, 3]) <class 'tuple'>

函数的传参:

#实参
1 位置参数 按照顺序,一一对应
2 关键字参数 可以不按照顺序,但是必须一一对应
3 混合参数 关键字参数一定要在位置参数后面
#形参
1 位置参数 按照顺序,一一对应
# 默认参数

l1 = [1,2,3]
s = 'fjkdsfljsdklfjskdfdsfsdafsd'
def my_len(argv): # 形式参数,形参
#函数体
count = 0
for i in argv:
count += 1
return count

# print(my_len(l1)) # 函数的执行者(实参) 实际的参数

result:3

# print(my_len(s)) # 函数的执行者(实参) 实际的参数

result:27

# 实参
# 位置参数 按照顺序,一一对应

def func1(x,y):
  print(x,y)

func1(1,2)

result:1,2

三元运算:只针对于简单的if else 这样的结构,才可以使用。

def compare(x,y):
  #if x > y:
     #return x
 #else:
     #return y
 #ret = x if x > y else y
 return x if x > y else y
print(compare(1001,100))

result:1001

关键字传参 可以不按照顺序,但是必须一一对应

def func1(x,y):
return x+y
print(func1(y=100,x=99))
result:199

混合传参: 关键字参数一定要在位置参数后面

def func1(a,n,b,x,y):
return x+y

name = 'alex'
print(func1(100,200,name,y=100,x=99))
result:199

# 形参角度
# 位置参数 按照顺序,一一对应
# 默认参数:给其传值,将原默认参数覆盖掉,不传值,不报错,使用默认值
# 应用场景:不经常改变的参数,但是一直在用。

def func1(x,y,a=666):
print(x,y,a)
func1(1,2)
func1(1,2,333)
result:

   1 2 666
   1 2 333

# 默认参数的陷阱
# 默认参数若是可变的数据类型,他始终使用的是一个内存地址。

def func1(x,l1=[]):
l1.append(x)
return l1
ret = func1(1)
print(ret,id(ret))
ret1 = func1(100)
print(ret1,id(ret1))

result:

  [1] 1975667679880
  [1, 100] 1975667679880

动态参数:

def func1(*args,**kwargs):  # 在函数的定义时,在 *位置参数,聚合。
# *args 将所有的实参的位置参数聚合到一个元组,并将这个元组赋值给args
print(args)#(1, 2, 3, 4)
print(kwargs)#{'name': 'abby', 'age': 1000}
func1(1,2,3,4,name='abby',age=1000)

在函数的定义时,在 *位置参数,**位置参数聚合。

l1 = [1,2,3]
l2 = [111,22,33,'abby']
def func1(*args):
print(args)#([1, 2, 3], [111, 22, 33, 'abby'])
return args[0] + args[1]
print(func1(l1,l2))#[1, 2, 3, 111, 22, 33, 'abby']

在函数的调用(执行)时,在 *位置参数,**位置参数打散。
l1 = [1,2,3]
l2 = [111,22,33,'abby']
def func1(*args,):
print(args)
print(kwargs)

func1(*l1,*l2)#(1, 2, 3, 111, 22, 33, 'abby')

func1(*(1,2,3),*('abby','sb'))#(1, 2, 3, 'abby', 'sb')
func1(*'abby',*'sb')#('a', 'b', 'b', 'y', 's', 'b')func1(**{'name':'abby'},**{'age':1000})#{'name': 'abby', 'age': 1000}

形参的顺序
# 位置参数,默认参数
def func(a,b,sex='男'):
return a,b,sex
print(func(100,200,))#(100, 200, '男')

# 位置参数,*args, 默认参数
def func(a,b,*args,sex='男',):
print(a,b)#100 200
print(sex)#男
print(args)#(1, 2, 34, 5, 6)
func(100,200,1,2,34,5,6)

# 位置参数,*args, 默认参数 **kwargs
def func(a,b,*args,sex='男',**kwargs,):
print(a,b)#100 200
print(sex)#nv
print(args)#(1, 2, 34, 5, 6)
print(kwargs)#{'name': 'abby', 'age': 1000}
func(100,200,1,2,34,5,6,sex='nv',name='abby',age=1000)

我们首先回忆一下Python代码运行的时候遇到函数是怎么做的,从Python解释器开始执行之后,就在内存中开辟里一个空间,每当遇到一个变量的时候,就把变量名和值之间对应的关系记录下来,但是当遇到函数定义的时候,解释器只是象征性的将函数名读如内存,表示知道这个函数存在了,至于函数内部的变量和逻辑,解释器根本不关心。

等执行到函数调用的时候,Python解释器会再开辟一块内存来储存这个函数里面的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量回储存在新开辟出来的内存中,函数中的变量只能在函数内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。

我们给这个‘存放名字与值的关系’的空间起了一个名字-------命名空间。

代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间;

在函数的运行中开辟的临时的空间叫做局部命名空间。

# python中,名称空间分三种:
# 全局名称空间
# 局部名称空间(临时)
# 内置名称空间

# 作用域:
# 全局作用域 全局名称空间 内置名称空间
# 局部作用域 局部名称空间(临时)

# 取值顺序: 就近原则
# 局部名称空间 ----> 全局名称空间 ----->内置名称空间 单向从小到大范围

len = 6
def func1():
len = 3
func1()
print(len)#6

def len(l):
return l
print(len([1,2,3]))#[1, 2, 3]

# 加载顺序
# 内置名称空间 ----> 全局名称空间(当程序执行时) --- > 局部名称空间(当函数调用的时候)

函数的嵌套:

def func1():
print(111)
def func2():
print(222)
func1()
print(333)
print(666)
func2()
print(555)
result:
666
222
111
333
555

def func1():
print(222)
def func2():
print(333)
print(111)
func2()
print(666)
func1()
result:
222
111
333
666

# global nonlocal
# 局部名称空间 对全局名称空间的变量可以引用,但是不能改变。
def func1():
count = 2
print(count)
func1()
result:2

count = 1
def func1():
count = count + 1 # local variable 'count' referenced before assignment
print(count)
func1()
result:局部中没有定义,所以他会报错
# 如果你在局部名称空间 对一个变量进行修改,那么解释器会认为你的这个变量在局部中已经定义了

# global
# 1,在局部名称空间声明一个全局变量。
def func2():
global name
name = 'abby'
func2()
print(name)
result:abby

# 2,在局部名称空间可以对全局变量进行修改。
count = 1
def func1():
global count
count = count + 1
print(count)
func1()
print(count)
result:
2
2

# nonlocal
# 子函数对父函数的变量进行修改。
# 此变量不能是全局变量。
# 在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,
# 并且引用的哪层,从那层及以下此变量全部发生改变。

def func1():
count = 666
def inner():
print(count)
def func2():
nonlocal count
count += 1
print('func2',count)
func2()
print('inner',count)
inner()
print('func1',count)
func1()
result:
666
667
667
667

 


 
 

 

猜你喜欢

转载自www.cnblogs.com/mingxi/p/12344809.html