函数

函数;
  目的:重复使用
  函数名是函数的引用
  函数中的局部变量和全局变量同名,用global声明
  参数可以是数据类型和函数
  参数可以是值和函数
  返回值可以是值和函数,默认返回None

  函数名:
    函数名也是变量,函数名就是一个引用
  函数调用:
    函数名是一个引用,指向函数对象,因此可以把函数名赋给一个变量,让变量指向函数对象,相当于给这个函数起个别名
  返回值:
    return语句:
      目的:结束函数,返回值
      python函数和方法默认都有返回值,默认返回值是return None
      return None可以简写为return
      return语句返回多个值:返回多个值就是返回一个tuple,返回tuple时,函数可以省略括号,而多个变量接收一个tuple,按位置赋给对应的值
  函数作为返回值
      展示形式是,在函数内部,在定义一个函数,执行外部函数的时候,返回内部函数
      返回函数就是执行函数,并返回值

 

参数列表:
  函数需要传入3个参数,当传入list时相当于一个参数
  在 python 中,strings, tuples, 和 numbers 是不可变对象,而 list,dict 等则是传可变对象。
  传不可变对象,传入参数时按值传递,不会改变自身
  传可变对象,传入参数时按引用传递,会改变自身

  函数和方法的参数能用父类的用父类,这是原则
  默认参数必须指向不对对象:
    原因-默认参数的值在函数定义时就已经计算出来的
  函数的参数可以是变量,或者函数
    因为变量指向函数,所以对一个函数可以直接传入函数当作参数,这种函数叫做高阶函数
默认参数
  作用:默认参数可以简化函数的调用,可以少传几个参数
  设置默认参数注意点:
    1是必选参数在前,默认参数在后,否则python解释器会报错
    2是如何设置默认参数
  当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以当作默认参数
  有多个默认参数时,调用函数时候,既可以按顺序提供默认参数,没有提供的参数使用默认值
  当不按顺序提供部分默认参数时,需要把参数名写上。比如调用enroll('Adam', 'M', city='Tianjin')
  在函数定义时,默认参数的值就被计算出来了,且只计算一次
可变参数
  顾名思义,可变参数就是传入的参数个数是可变的
  只需要在参数前面加个星号*就可以了
  已经有一个list或者tuple了,怎么调用一个可变参数
  Python允许你在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去
  可变参数允许你传入0个到任意个元素
  list和tuple算一个值
  可变参数和定义list参数有什么区别:
    list参数相当于一个参数,传入参数也是一个list
  调用函数时传入可变参数,*list,把一个tuple拆分成多个元素,传入多个参数,可传入位置参数,默认参数,可变参数中
  调用函数时传入多个参数,**dict,把一个dict拆分成多个元素,传入多个参数,可传入命名关键字参数,关键字参数
  函数内部接收:
    传入多个可变参数,函数内部自动会把这些参数组成一个tuple
    传入多个关键字参数,函数内部自动会把这些参数组成一个dict
  要注意定义可变参数和关键字参数的语法:
    *args是可变参数,args接收的是一个tuple;
    **kw是关键字参数,kw接收的是一个dict。
  可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过*args传入:func(*(1, 2, 3));
  关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过**kw传入:func(**{'a': 1, 'b': 2})。
  使用*args和**kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
  关键字参数
    关键字参数有什么用?它可以扩展函数的功能,把用户相传的参数传上来

 


为什么要设计str、None这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。
参数:
  参数超过5个时需要打包传,把参数都传入list中
  局部变量的作用域是在函数内,局部变量在执行函数时创建,函数执行完成后删除,也就是说在函数外部局部变量不存在
  局部变量名字和全局变量的名字相同,同名的局部变量就是新的变量
  函数内改变全局变量用global关键字
  局部变量和全局变量用不同的名字
  global globvar # 使用 global 声明全局变量
  globvar = 1
2、一个global语句可以同时定义多个变量,如 global x, y, z。

函数的结束:
  函数执行到最后一条语句或是遇到return时结束

高级函数:
  变量可以指向一个函数=====>函数名就是一个变量
  因为变量指向函数,所以对一个函数可以直接传入函数当作参数,这种函数叫做高阶函数
  高阶函数就是让函数的参数接收别的函数
  map(),reduce(),filter(),sorted()
  对于函数我们只关心参数和返回值,以及函数的作用
  返回值:可以是函数、变量、多个变量
闭包:
  闭包的概念:内部函数保存外部函数的参数和局部变量指向的引用
  我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。
  当一个函数返回值是他的内部函数时,相关参数和变量都保存在返回函数中
  相关参数保存的是值,变量保存的是引用,变量一般保存的都是引用,
  所以返回闭包时牢记的一点就是:返回函数中变量不要引用任何循环变量,或者后续会发生变化的变量。
  def count():
  fs = []
  for i in range(1, 4):
  def f():
  return i*i
  fs.append(f)
  return fs

  f1, f2, f3 = count()

  >>> def count():
  ... fs = []
  ... for i in range(1, 4):
  ... def f(j):
  ... def g():
  ... return j*j
  ... return g
  ... fs.append(f(i))
  ... return fs
  ...
  >>> f1, f2, f3 = count()
  >>> f1()
  1
  >>> f2()
  4
  >>> f3()
  9


匿名函数:
  目的:
  懒得定义一个函数,或者为了和别的函数名不冲突
  一般使用一次
  使用方式:
  lambda x:x*x lambda关键字定义匿名函数,冒号前面是参数,冒号后面是表达式
  限制:只有一个表达式,不用写return,返回值就是该表达式的值
  作用:用匿名函数的有个好处,因为函数没有名字,不必担心函数名冲突。此外匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数
  匿名函数也可以用来当返回值



装饰器:
  目的:不改变函数内部的代码,在函数运行期间动态的增加功能的方法
  装饰器:decorator就是一个函数,他可以接收一个函数,并返回一个函数,新功能都在返回的函数中,返回的函数中又调用了传入的函数
  在函数运行期间动态的增加功能的方式
  使用方式:
  由于在python中函数也是一个对象,所以函数可以赋值给变量,所以通过变量也能调用该函数
  对于任意函数,都可以用func(*args,**kw)的形式调用它,无论函数的参数如何定义
  函数名字赋值给变量,以及把函数名()赋值给变量的区别
  把一个函数赋值给变量,把一个函数的返回值赋值给变量
  B return一个函数,那么这个函数什么时候,那么在B()运行时就会执行这个函数
  在函数中定义一个新函数,并把新函数当作返回值返回
  装饰器本质是一个函数,调用时通过注解来调用
  @log
  def now():
  print '1' 等于 now=log(now)
  三层嵌套的decorator相比now=log('exute')(now)
  表现形式:在函数的方法上面@log,表示装饰器,
  现在,只需记住在定义wrapper()的前面加上@functools.wraps(func)即可,装饰器函数中的功能函数需要跟上这句话,保持函数签名为传入函数的签名
  decorator可以增强函数的功能,定义起来虽然有点复杂,但使用起来非常灵活和方便。

  @log
  def now():
  print '2013-12-25'

  def log(func):
  def wrapper(*args, **kw):
  print 'call %s():' % func.__name__
  return func(*args, **kw)
  return wrapper

偏函数:
  目的:
  设置函数参数为默认值
  怎么用偏函数:
  传入函数对象和默认参数,生成一个新函数
  functools.partial(int,base=2)的作用:就是把一个函数的某些参数设置固定值,返回一个新函数,调用该函数会更简单

  >>> import functools
  >>> int2 = functools.partial(int, base=2)
  >>> int2('1000000')
  64
  >>> int2('1010101')
  85

python访问修饰符:
  正常的函数和变量都是公开的
  __XX__形式的变量是特殊变量,有特殊作用的变量,如__name__,__author__
  类似_xx,__xx形式的函数和变量是非公开的private,不应该被直接应用,如_abc,__abc
  定义public还是private是根据函数和变量要不要被外部调用的,如果需要外部调用的就用public,如果不需要外部调用的就是private


空函数:
  没有函数体的函数叫空函数
  def nop():
  pass
  pass用来当做占位符,让代码能运行起来,缺少了pass,代码运行时会有语法错误

12、对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的
*args会把一个tuple拆分成多个元素,传入多个参数,可传入位置参数,默认参数,可变参数中
**kw会把一个dict拆分成多个元素,传入多个参数,可传入命名关键字参数,关键字参数


























posted on 2018-01-15 17:19  悬剑  阅读(116)  评论(0)    收藏  举报

导航