三、函数

 

函数封装

def  函数名(参数):

  函数体

以后就可以直接调用  函数名

return返回的是对象

return和yield的区别,前者硬性 遇到就返回, 后者跳出来 生成器

 

 

函数参数

语法 :func(positional args,keyword_args, *tuple_nonkw_args,**dict_kw_args)

                     位置                 关键字                 非关键字               关键字不定长

传递方式:

位置参数  要一一对应

关键字参数  def foo1(x, y,intro=“教育”) 

      foo1(“教育机构”,“网址”)

类似C++的默认构造函数

def mysun(*args) #位置参数包裹以及使用*

  return args

type(mysum(5, 6, 6))   #tuple

传递参数不受限制

 

def filmInfo2(**kwargs) #关键字包裹以及使用**

  print(type(kwargs))

  for key, value in kwargs.items():

    print(key, ':', value)

filmInfo2(film='让子弹飞', box=7.5,rate =8.0,price = 60)

 

#解包

def scoreReport(name,age, *args, course = 'python', **kwargs):

  print('个人信息:', name, age)

  for item in args:

    print('--->'item)

  print('课程信息', course)

  print('每节课的成绩:')

  for key.value in kwargs.item():

    print('>>>',key, value)

  scoreReport('jace', 25, '高中部', '三年一班', 'xuoweihao:40', lesson = 85, lesson2=90)

 

def filmInfo(**kwargs):

  print(type(kwargs))

  for key,values in kwargs.item():

    print(key, ':', values)

dl =['film':'xiuxiude tiequan',box=6.5, prince=60, actor= ='shenteng']

filmInfo(**dl)

#题外话,字典形式的写法,如果遇到数字类型的时候怎么写

dl ={'film':'xiuxiude tiequan','box':'6.5', 'prince':'60', 'actor':'shenteng'}

filmInfo(**dl)

 ################################################################

companyName='七月在线'

 

def getCompany():

  url = 'http.julyedu.com'

  return companyName

getCompany()

越是内部的就越是能访问外部的,反之很难

函数执行完之后就不存在了,除非下一次调用

 

url='julyedu.org' # 全局

 

def getUrl():

  url = 'http.julyedu.com' #局部

  return url

getUrl()

返回的是内部的

 ###################################################################

偏函数PFA

使用场景:如果一个函数的参数很多,而在每次调用的时候有一些又经常不需要指定的,

就可以使用(偏函数相当于默认值)

语法: partical(func, *args, **keywords)

  from functools import partial

原理:创建一个新函数,固定住原函数的部分参数(可以为位置参数、关键字参数)

例如,将16进制的字符串转化成十进制的

def hex2int1(num):

  return (str(num),base = 16) #base为关键字参数这个在调用int函数时,固定给16

hex2int('F')  #为什么名字不一样呢?

偏函数方法

import functools

hex2int2 = functools.partial(int, base = 16)

hex2int2('A')

# 偏函数能固定位置参数吗? 能

max100= functools.partial(max, 100) # 定义一个叫max100的偏函数,将这个偏函数的第一个值固定为100

max100(101) # 这时候调用它,传入值,与100进行比较

 

type(max100) # 偏函数的类型与普通函数不一样

##############################################

递归

def fool(num):

  if len(num)==1;

    return num[0]

  else:

#    print(num[0], '>' *6)

#    print(num[1: ], '  ' *6)

    return num[0] + fool(num[1: ])

fool([1, 2, 31, 5, 6, 55])

 

#函数名本质即变量,同一个函数对象可以被多个变量引用

def foo(): # 新建一个函数对象,并用foo这个变量名对其进行引用

  pass

def foo # 对函数对象的引用可以删除

 #回调函数

def mycalucate(*num)
  return max
callbackfunc(53,5,33)

 

num=-1

a=b=abs

#引用

print(abs, a)

 

#调用

a(num)
b(-8,8)
c(7)

 

#高阶函数

一个函数接收另一个函数作为参数传入

回调函数:函数作为调用函数的结果返回

函数对象既然可以被引用,那可以作为参数被传入或作为结果被返回吗? 

可以

 

bifs

内置的高阶函数有:

l1=[2,3,5,9, 'julyedu.com', [2, 3, 3], 5, 2]

filter

语法:filter(function, list)

函数f的作用是对每个元素进行判断,返回true or false

filter()根据判断结果自动过滤不符合条件的元素,返回符合条件的新list

list(filter(lambda) x:True if type(x)== str else False, l1)

def myfilter(x):

  if x>60:

    return True

  else:

    return False

myfilter(62)

l1=[1,62,57]

filter(myfilter, l1)

 

 

 

#map

#语法:map(function, list)

#让list的每一个元素依次调用   function并获取返回值存入一个新的 list中

list(map(lambda x:(x, l1. count(x)), l1))

 

#reduce 

语法:reduce(function, list)

函数function必须包含两个参数, optional可选,如果存在则表示初值为 optional

reduce() 对list的每个元素反复调用函数 f,并返回最终结果值 

from functools import reduce

reduce(lambda a, b:a+b, [1,2,3,4,5,6,7,8])

求和值返回 36

reduce 只能是两个变量,不可以三个等等

#############################################################

变量的作用域

闭包closure:涉及嵌套函数时才有闭包问题

内层函数引用了外层函数的变量(参数),然后返回内层函数的情况

 

装饰器

 

函数式编程

 

###########################################################

匿名函数lambda

print(type(lambda a, b:a**b ))

定义

函数体

不用写return

使用一:作为正常函数使用,不推荐

foo=lambda x, y:x+y   #不用写return

print(foo(5, 6))

使用二:lambda关键字定义在高阶函数的参数位上

d1={'china':15, 'India':9, 'usa':2, 'japan':1.5}

sorted(d1.items(), key=lambda x:(x[0], x[1])) # 按d1.items()第0个元素升序,国家名

# sorted(d1.items(), key=lambda x:(x[1])) # 按d1.items()第1个元素升序,人口数

 

闭包

def fop4():

  for i in range(5):

    yield i

    yield 'f'  #加入一个yield看看会不会被执行

    i+=1 

nums_in_global=[15,2,3,9,3,2] #声明一个全局
def foo1(nums_in_function):
  print('nums_in_function此时是foo1中,可以被访问:', nums_in_function)
  def foo2():
    return max(nums_in_function)
  return foo2
#print(nums_in_function) #此时已经消失了,name 'nums_in_function' is not defined
#调用
foo1([5,3,8])

###################################################################

装饰器

 

def foo1():
  print('this is foo1 function')
  print(datetime.datetime.now())


import datetime
def printime():
  print(datetime.datetime.now)

def foo1():
  print('this foo1')
  printime()
def foo2():
  print('this is foo2 function')
def foo3():
  print('this is foo3 function')
def extratime(func):
  print(datetime.datetime.now())
  return func # 利用回调

decorated=extratime(foo2)
decorated()

每一次都要写,还是很麻烦

import datetime
def extrafoo(func):
  def inner():
    print('extra:', datetime.now())
    print('from inner to execute:', func._name_)
    print('the', func._name_, 'result:', func())
  return inner
@extrafoo #装饰器特性,被装饰的函数定义之后立即运行
def foo1():
  return 'this is fool function'

#@是Python 装饰器的简便写法,也叫语法糖

#装饰器语法糖在要被包裹的函数前声明。@后面的函数名,是包裹下边函数的函数名extrafoo

装饰器使用方便的原因:

1)python的函数像普通的对象一样能作为参数传递给其他的函数

2)可以被赋值给其他变量,可以作为返回值, 定义在另一个函数内

注:return后面有函数名,return的是什么?

  永远是个[]对象!

posted @ 2018-02-07 19:40  谦曰盛  阅读(203)  评论(0编辑  收藏  举报