首页 > 技术文章 > 五、Python之函数

wangruoxu 2021-09-16 14:23 原文

序言

为了增加代码的复用性,站在前人的肩膀上继续前进,任何一门语言发展至今都积累了大量的代码。函数是代码的一种封装形式(此外在OPP中还有方法等等),为后来者提供方便的调用接口,避免重复造轮子。本篇旨在讲述Python如何创建和调用函数、函数参数、函数作用域、以及递归等知识。

函数创建和调用函数

# 创建函数
def myFunction(para1=P,para2,): # Python中没有数据类型这一概念,同样函数返回值也不需要标注类型
  . 
  .
  .
return 

# 调用函数
>> myFunction() 

函数参数

  • 实际参数与形式参数
    实际参数是main函数中调用函数时给定的,传递给形式参数
  • 默认参数
    函数调用时没有传递实参,此时启用默认参数。
  • 关键字参数
    在定义函数时一般把参数的名字和位置确定下来了,我们一般按照函数定义时的参数位置给出形参值这叫位置参数,而用关键字参数可以不按照函数定义里的相对位置直接利用形参赋值的方式进行。
  • 收集参数(可变参数)
    当函数并不知道调用者实际会传入多少个实参时,就需要利用收集参数。
def test(*params,extra):
  print("有%d个参数" %len(params))
  print("第二个参数是:",params(1)) # 可见Python将收集参数打包成了一个元组,通过传递首地址
# 和偏移值实现可变参数传递

>> test('w','a','n','g',extra='fei') #在收集参数后面

编写查看函数文档

  def myFunction(params):
  '''
  函数文档说明区
  '''
>>print(myFunction._ _doc_ _) #查看函数说明文档
>>help(myFunction) #查看函数说明文档

变量作用域

  • 局部变量
    定义在函数内部(即非main中定义的变量)的变量是局部变量,局部变量的作用范围只在函数内部,在函数外部其不能被引用。
def discount(price_o,rate):
  price_new=price_o*rate
  return price_new

>>pay=discount(price_o,rate)
>>print('%d'%(pay))
>>print('%d'%(price_new)) # Error:'price_new' is not defined
  • 全局变量
    定义在main中的变量是全局变量,在自定义函数中尽量不要去修改它,仅仅去访问它就好,由于Python的屏蔽机制,如果在自定义函数中不结合globle关键字,对全局变量的修改也是失败的。注意以下两个例子:
>> count=5 # count是全局变量
   def myFun():
   count=10 # myFun函数中试图修改count的值
   print(count)

>>myFun()
10
>>count
5        # 事实证明,myFun函数修改count的值失败
>> count=5 # count是全局变量
   def myFun():
   globle count # 申明count是来自外部的全局变量
   count=10 # myFun函数中试图修改count的值
   print(count)

>>myFun()
10
>>count
10       # 事实证明,myFun函数修改count的值成功

闭包

维基上解释地过于复杂,自己也没有看懂,结合一个例子理解一下。

>>def funX(x):
    def funY(y):
      return x*y
    return funY

>>temp=funX(8)
'''
temp=funX(8)=
def funX(8):
  def funY(y):
    return 8*y
  return funY
'''
>>temp(5)
40

>>temp(10)(5)
500

由上图可见闭包就相当于返回一个内嵌函数的值。

lambda创建匿名函数

>>m=lambda x,y : x*y # lambda可以简化函数定义过程,代码简洁、可读性强
>>m(2,10)
20

两个厉害的BIF

## filter()过滤器 ##
# filter(myFunctionName/None,iterable),将可迭代对象(列表、元组)的每个对象送入myFunction中计算,所有结果为True的则打包成一个filter类型输出。
>>temp=filter(lambda x:x%2,range(10))
>>list(temp)

## map()映射器 ##
# map(myFunctionName/None,iterable),将可迭代对象(列表、元组)的每个对象送入myFunction中计算,加工后的结果打包成一个map类型输出。
>>temp=map(lambda x:x%2,range(10))
>>list(temp)

函数嵌套定义与递归

函数嵌套定义就是在一个函数内部定义其他函数。递归就是一个函数调用自身,其中机理设计栈,以后在算法篇,再谈谈栈。

推荐阅读