柚子快报邀请码778899分享:python的函数

http://yzkb.51969.com/

一、函数介绍

1、函数是什么?

函数一词来源于数学,编程中的"函数"与数学中的函数有很大的不同。  (BASIC中叫subroutine,C中叫function,java中叫method)

定义:函数是指将一组语句的集合通过一个名字(函数名)封装起来,想执行这个函数,只需调用其函数名即可。 

2、为什么要使用函数?

(1)减少重复代码:否则遇到重复的功能只能重复编写实现代码,代码冗余

(2)使程序变得可扩展:否则功能需要扩展时,需要找出所有实现该功能的地方修改之,无法统一管理且维护难度极大 

(3)使得程序变得易维护:否则代码的组织结构不清晰,可读性差

3、函数分类

(1)内置函数:针对一些简单的功能,python解释器已经为我们定义好了的函数即内置函数。对于内置函数,我们可以拿来就用而无需事先定义,如len(),sum(),max()。

(2)自定义函数:很明显内置函数所能提供的功能是有限的,这就需要我们自己根据需求,事先定制好我们自己的函数来实现某种功能,以后,在遇到应用场景时,调用自定义的函数即可

二、函数的参数

  参数的作用:可以让函数更灵活,不只能做死动作,还可以根据调用时传参的不同来决定函数内部的执行流程。

# 无参函数

def sayhi(): # 函数名(小写即可)

print("Hello,I'm nobody!")

sayhi() # 调用函数,函数名指向上述代码指向的内存位置,加上括号才是执行代码

print(sayhi) # 函数sayhi指向的内存地址

# 单个参数的函数

def sayhi(name):

print("hello",name)

print("my name is black girl....", name)

sayhi("tracy")

# 多个参数函数

def calc(x,y): # 定义算数函数

res = x**y

return res # 返回函数执行结果

a,b = 5,8

c = calc(a,b) # 结果赋值给变量c

print(c)

calc(2,10) # 直接写入参数

1、形参

  只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量

2、实参

  可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值

def calc(x,y): # 形参

res = x**y

return res

a,b = 3,5

c = calc(a,b) # 实参

print(c)

d = calc(2,3) # 实参

3、默认参数

def stu_register(name,age,country,course):

print("注册学生信息".center(50,'-'))

print("姓名:",name)

print("age:" ,age)

print("国籍",country)

print("课程",course)

stu_register("山炮",22,"CN","python_devops")

stu_register("丰收",23,"CN","linux")

'''

由于很多人国籍都是中国,可以将country设置为默认参数

默认参数:

'''

def stu_register(name,age,course,country="CN"): # 非默认参数不能跟在默认参数后面

print("registration info".center(50,'-'))

print(name,age,country,course)

stu_register("jack",22,'c++') # 实参和形参按顺序一一对应

stu_register("rain",32,'dance','Korean')

stu_register("Alfa",21,'python')

4、关键字参数

  应用场景:正常情况下,给函数传参数要按顺序,不想按顺序可以用关键参数  定义:指定了参数名的参数就叫关键参数     关键参数必须放在位置参数(以位置顺序确定对应关系的参数)之后

def stu_register(name,age,course,country='CN'):

print("注册学生信息".center(50,'-'))

print("姓名:",name)

print("age:" ,age)

print("国籍",country)

print("课程",course)

stu_register("绮珊",course='Python',age=22,country='JP') # 后三个均为为关键参数置于name位置参数之后

# stu_register("杉树",course='Python',22,country='JP') # 22为位置参数不能放在关键参数course之后

# stu_register("曼玉",22,age=25,country='JP') # age获得多个赋

5、非固定参数(动态参数)

  形式参数中出现*,传递的参数就可以不再是固定个数,会将传过来的所有参数打包为元组。

def send_alert(msg,*users):

for u in users:

print('报警发送给',u)

# 方式一:

# 报警,十个运维人员

send_alert('注意系统资源别浪了','Alex','jack','tracy','wood')

# 方式二:

# send_alert('注意内存紧张',['alex','jack','tracy','wood']) # 传入的参数是数据

send_alert('注意内存紧张',*['alex','jack','tracy','wood']) # 传入的参数是数组内的元素

# 传入的参数由(['alex','jack','tracy','wood']) ————>('alex','jack','tracy','wood')

  如果动态参数后还有参数

# 方法一:

def send_redalert(msg,*users,age):

for u in users:

print('CPU紧张',u)

# send_redalert("alex","rain",22) # 22也会传递给*users

send_redalert("alex","rain",age=22)

# 方法二:

def func(name,*args,**kwargs):

print(name,args,kwargs)

func('Alex',22,'tesla','500w',addr='湖北',num=123332313)

# Alex (22, 'tesla', '500w') {'addr': '湖北', 'num': 123332313}

d = {'degree':'primary school'}

func('Peiqi',**d)

*args代表位置参数,它会接收任意多个参数并把这些参数作为元组传递给函数。

**kwargs代表的关键字参数,允许你使用没有事先定义的参数名。

位置参数一定要放在关键字参数的前面。

  优点:使用*args和**kwargs可以非常方便的定义函数,同时可以加强扩展性,以便日后的代码维护。 

三、函数的返回值

  返回值:函数外部的代码要想获取函数的执行结果,可以在函数里用return语句把结果返回。注意:  1、函数在执行过程中只要遇到return语句,就会停止执行并返回结果,可以理解return语句代表着函数的结束  2、如果未在函数中指定return,那这个函数的返回值为None

def stu_register(name,age,course='PY',country='CN'):

print("注册学生信息".center(50,'-'))

print("姓名:", name)

print("age:", age)

print("国籍", country)

print("课程", course)

if age > 22:

return False

else:

return True

registration_status = stu_register('阿斯顿',22,course="全栈开发",country='JP')

if registration_status:

print("注册成功".center(50,'-'))

else:

print("too old to be a student.")

'''

执行到return语句后,停止执行函数并返回结果

'''

def stu_register(name,age,course):

print(name,age,course)

#

# if age > 22:

# return 'sdfsf' # 返回值可以是任意值

# else:

# return True

#

# return None # 到return语句后,停止执行函数并返回结果

# print('hahah')

# return 1

return [name,age]

status = stu_register('Peiqi',29,'安保')

print(status)

四、全局和局部变量

局部变量:函数内定义的变量,只能在局部生效全局变量:定义在函数外部一级代码的变量,整个程序可用(由上到下可用)      在函数内部可以引用全局变量。变量查找顺序:如果全局和局部都有一个变量,函数查找变量的顺序是由内而外的。两个函数间互不可见

name = "Black girl" # 全局变量

def change_name():

# global name # (不建议使用global)在函数内修改全局变量,不能放在函数内局部变量后面

name = "黑色的姑娘" # 局部变量

print("在",name,"里面...",id(name))

change_name()

print(name,id(name)) # 与函数内的变量内容完全不同

'''

输出结果:

在 黑色的姑娘 里面... 4302993904

Black girl 4316351984

'''

  函数内可以修改字典、列表、集合、对象、类、元组内的列表

names = ['Alex','Black Girl','Peiqi']

def change_name():

names = ['Alex']

del names[2] # names整体的内存地址不能修改只能引用,但其内部的元素是可以修改的

names[1] = "黑姑娘"

print(names)

change_name()

print(names)

'''

输出结果:

['Alex', '黑姑娘']

['Alex', '黑姑娘']

'''

在函数中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。

全局变量作用域是整个程序,局部变量作用域是定义该变量的函数。

当全局变量与局部变量同名时,在定义局部变量的函数内,局部变量起作用;在其它地方全局变量起作用。

五、作用域(scope)

  作用域定义:一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

python中一个函数就是一个作用域,局部变量放置在其作用域中

C# Java中作用域{}

代码定义完成后,作用域已经完成,作用域链向上查找

age = 18

def func1():

age = 73

def func2():

age = 84

print(age)

return 666

val = func1()

print(val)

'''

输出:666

'''

# 函数名可以当作返回值

age = 18

def func1():

age = 73

def func2():...

return func2 # 返回一个函数名# val = func1()

print(val)

'''

输出:.func2 at 0x101462598>

'''

# 代码写完之后作用域已经生成,不管函数名传到哪里,只要执行都回回定义的地方往上找

age = 18

def func1():

age = 73

def func2():

print(age)

return func2 # 返回一个函数名不带括号

val = func1()

val()

'''

输出结果:73

'''

六、嵌套函数

  嵌套函数,就是指在某些情况下,您可能需要将某函数作为另一函数的参数使用。

1、函数定义完成之后,没有通过名字调用,内部代码永远不会执行

def func1():

print('alex')

def func2():

print('eric')

func1()

'''

输出:alex

'''

def func1():

print('alex')

def func2():

print('eric')

func2()

func1()

'''

输出:

alex

eric

'''

  总结:

函数内部可以再次定义函数

执行函数需要被调用

2、嵌套函数寻找变量,优先自己函数,再找父级、爷爷级等,没有就找全局变量(一层一层往上找)

age = 19

def func1():

age = 73

print(age) # 寻找变量,先找自己的函数内,没有就找全局变量(一层一层往上找)

def func2():

age = 84

print(age) # 寻找变量,优先自己函数、再找父级、爷爷级,最后找全局变量

func2()

func1() # 输出:73 84

# 测试二:

age1 = 19

def func1():

age1 = 73

def func2():

print(age1) # 按顺序往上找,找到父级的age=73

func2()

func1() # 输出:73

3、局部变量位置调整

age = 19

def func1():

def func2():

print(age)

age = 73

func2()

func1()

"""

输出:

73

"""

age = 19

def func1():

def func2():

print(age)

func2()

age = 73

func1()

'''

执行报错:free variable 'age' referenced before assignment in enclosing scope

73在func2后面,func2不知道该取哪个参数

'''

  为了避免这种情况,声明变量尽量写在前面。

4、全局变量设置

age = 19

def func1():

global age # 此时已经拿到age=19,age=73还没有执行

def func2():

print(age)

func2()

age = 73 # 此时修改全局age=73

func1()

print(age)

"""

输出:

19

73

"""

age = 19

def func1():

global age

def func2():

print(age)

age = 73 # 将全局变量age改为73,再执行func2,函数没有在func2\func1中找到age,继续到全局找age,但全局已经修改为73

func2()

func1()

print(age)

"""

输出:

73

73

"""

  第一个程序,在global age时,函数已经拿到age=19,但此时age=73还没有执行,此时执行func2函数,打印age=19。随后修改全局变量age=73,直接打印age,因此输出73.

  第二个程序,在global age时,函数拿到age=19,随后修改全局变量age=73,接着执行func2函数,打印age=73,打印此时的全局变量age,也同样输出73.

 

柚子快报邀请码778899分享:python的函数

http://yzkb.51969.com/

文章来源

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。