Loading

python0.9-----函数

函数:

概述:在一个完整的项目中,某些功能会反复使用,那么会将功能封装成函数,当要使用功能时,直接调用函数即。

优点:

一:简化代码结构,增加了代码的复用度(重复使用的程度)。

二:如果想修改某些功能,或者修改某些或调试bug,只需要修改某些函数即可。

 

定义函数:

def 函数名(参数列表):

  语句

  return 表达式

 

解释:

def:函数代码块以def关键字开始。

函数名:遵循标识符规则,是要使用的功能的函数名字。

参数列表(参数1,参数2,......,参数n):任何传入函数的参数和变量必须放在圆括号之间,用逗号分隔.函数从函数的调用者那里获取信息。如果没有参数,小括号也不能省略。

冒号:函数内容以冒号开始,并且缩进。

语句:函数封装的功能。

return:用于结束函数的,并返回信息给函数的调用者.return后面的语句是不用执行的。

表达式:即返回给函数的调用者的信息。

注意:最后的return 表达式,可以不写,相当于return None。

 

函数的调用:

格式:函数调用(参数列表)

 

函数调用的本质:实参给形参赋值的过程。

实参(argument):调用函数是给函数传递的数据,本质是值。

形参(parameter):定义函数是小括号中的变量,本质是变量。

 

参数的传递:

值传递:传递不可变类型。number,string,turple,boolean,函数内部改变这些类型,函数外部对应的值不会改变。

引用传递:传递可变类型。dict,list,set,函数内部改变这些类型,函数外部对应的值会改变。

 

关键字参数:允许函数调用时参数的顺序与定义不一致。                                                       

例如:

def myPrint(str,age)

  print(str,age)

 

myPrint(age=18,str=’boboob’) :调用函数时age和str的顺序与形参的顺序不一致。

 

默认参数:调用函数是,如果没有传递参数,则使用默认参数。

例如:

def myPrint(str=’boboob’,age=0)

  print(str,age)

myPrint()

上述调用仍未出错,因为当没有传递参数时,str默认为‘bobboob’,age默认为0

另外:若使用默认参数,最好将默认参数放在最后。

例如:

def myPrint(str,age=0)

  print(str,age)

myPrint(‘boboob’)

 

不定长参数:

概念:能处理比定义时更多的参数。

加了星号(*)的变量args存放所有未命名的变量参数,如果在函数调用时,没有指定参数,它就是一个空元组。

例如:

def func1 (name,*args)

  print(name)

  for x in arr:      #遍历name的所有内容 

    print(x)

func1(‘bob’,’boboob’,’bobboobob’)

此时name=’bob’,args=(‘boboob’,’bobboobob’)

 

如果变量前面加上两个星号(**),则要求实参必须使用关键字参数,变量kwags为字典类型。如果在函数调用时,没有指定参数,它就是一个空字典。

def func2(**kwags)

  print(kwargs)

func2(x=1,y=2,z=3)

则kwages={‘x’:1,’y’:2,’z’:3}

 

下面这个函数可以接受任何类型的数据(若用关键字参数,则关键字参数应该全部在实参列表的右边)。

def func2(*args,**kwags)

  print(args,kwargs)

func2(1,1,2,x=1,y=2,z=3)

此时agrs=(1,1,2) kwargs={‘x’:1,’y’:2,’z’:3}

 

匿名函数:

概念:不使用def这样的语句定义函数,使用lambda来创建匿名函数。

特点:

1:lambda只是一个表达式,函数体比def简单。

2:lambda的主体是一个表达式,而不是代码块,仅仅只能在lambda表达式中封装简单的逻辑。

3:lambda函数有自己的命名空间,且不能访问自由参数列表之外的或全局命名空间的参数。

4:虽然lambda是一个表达式且看起来与内联函数一样,但事实上它C和C++的内联函数(减少使用的栈空间)不同,lambda表达式不能达到此效果。

格式:lambda 参数1,参数2,......,参数n:expression

例如:

sum=lambda num,num2 : num1 + num2

功能:return返回表达式(num1+num2)的值,给到sum。

 

装饰器是一个闭包,把一个函数当作参数返回一个替代版函数,本质上就是一个返回函数的函数。

用途:希望在不改变原函数的基础上给函数加上一些功能,这时候可以用装饰器这个技术。

 

#简单的装饰器:

#原函数定义:

def fun1():

  print(‘rundrun’)

 

 #装饰器定义:

def outer():

  print(‘**********’)

  func1()

#调用:

outer()

评价:虽然outer()函数起到了对fun1的装饰作用,但是没有返回函数,不符合装饰器的定义。

 

#若希望装饰器不仅仅能够作用于func1(),希望它能装饰更多的函数。

则:

#装饰器定义:

def outer(func):

  print(‘********’)

  func()

#调用:

outer(func1)

评价:虽然outer()函数起到了对任何函数的装饰作用,但是没有返回函数,不符合装饰器的定义。

 

#若希望装饰器返回函数:

#装饰器定义:

def outer(func):

  def inner():

    print(‘********’)

    func()

  return inner

调用:

func1=outer(func1)

评价:outer()函数不仅起到了对任何函数的装饰作用,并且返回装饰后函数inner,符合装饰器的定义,但是不够好。

 

#若希望装饰器返回函数,并装饰带有参数的原函数:

#原函数定义:

def func1(name):

   print('my name is %s' %name)

#装饰器定义:

def outer(func):

  def inner(name): 

    print(‘****************’)

    func(name)

  return inner

#调用:

new_func1=outer(func1)

new_func1('fish')

 

#简化调用方法:

def outer(func):

  def inner(name):

    print(‘****************’)

    func(name)

  return inner

#使用@符号将装饰器应用到函数。

@outer  #相当于省略func1=outer(func1)

#原函数定义:

def func1(name):

  print('my name is %s' %name)

#调用:

func1(‘fish’)

评价:这种装饰器起到了作用,但是只能装饰只有一个形参的函数,不通用。希望形参的数目不限,这样的要求才合理。

 

例如:以下装饰器可以装饰任何函数

#装饰器定义:

def outer():

  def inner(*args,**kwargs):

    #添加修饰的功能

    return func(*args,**kwargs)         #这里是先调用func函数,再返回func函数返回的#值。若是原函数无返回值也没有关系,它会返回元函数会返回None。

  return inner #这是返回一个函数。

@outer

#原函数定义:

def func1(name,age):
  print(‘my name is %s,my age is %d years old’ %(name,age))

  return ‘aaaa’

#调用:

func1(‘fish’,18)

 

偏函数:

概念:有些函数参数有默认值,若希望在不改动原有函数的情况下,修改参数的默认值,则可以使用偏函数的概念。

例如:

int(str,base=10) 这个函数的参数base默认值为10,表示str字符串是十进制字符串。可以自己定义偏函数,令base默认值为2。

 

#手动定义偏函数:

def int2(str,base=2):

  return int(str,base)

#调用:

int2(‘1010’)

 

#理论上函数不用自己定义,引入模块即可:import functools

int3=functools.partial(int,base=2)

int3和int2是一模一样的函数,int3的定义方式会更加简单。

posted @ 2018-06-18 19:50  FishLight  阅读(197)  评论(0编辑  收藏  举报