python函数

 

1 函数 function
1)什么是函数:

      函数是可以重复执行的代码块,可以重复使用

2)作用:

定义用户级的函数

3)语法:

def 函数名(参数列表):

语句块·····

语法说明:

a)      函数名是语句块的名称

b)      函数名的命名规则与变量名相同(标识符)

c)       函数的名字是一个变量,是绑定代码块的名称

d)      函数有自己命名空间,要让函数处理外部数据需要用参数给函数传入一些数据,如果不需要传入参数,参数列表为空

e)      语句块部分不能为空,如果为空需要填充pass语句

示例:

def  say_hello():

   print("hello world")

   print("hello tarena")

   print(0 + 19)

 

say_hello()          #执行正常

say_hello = 10

print(say_hello)        #执行正常

say_hello()                   #执行错误

解释:函数名和变量名相同,可以随意赋值,但是一般情况不能修改函数名

示例:

a=1000

b=129

def  mysum(a,b):

   print("调用 mysum(%s ,%s)" %(a,b))

mysum(10,10000)  #’’’调用 mysum(10,10000)" 此时a,b是实参 ,对函数之上的全局变量不管’’’

          解释:函数有自己命名空间,要让函数处理外部数据需要用参数给函数传入一些数据

 

4)函数的调用

函数名(参数列表)

调用说明:

a)      函数调用是一个表达式

b)      如果没有return语句,函数执行完毕后返回None对象

c)       如果函数需要返回其它的值对象需要用return语句

 示例:

   >>>def  h():

...    print("调用",h())   #··· 是要保持和>>>匹配,提示可以#在此输入

...

>>>         #返回None对象

 

return 语句

语法:

  return [表达式]

  [] 可省略

作用:结束当前函数的执行,返回到调用该函数的地方,同时返回一个值对象的引用关系

语法说明:

a)      return 语句后跟的表达式可以省略,省略后相当于return None

b)      如果函数内没有return语句,则函数执行完最后一条语句后返回None(相当于在最后一条return None语句)

c)       函数的调用可以返回一个值或一组值

示例

defsummmer(a,b):

    print(a+b)

    return '调用  '*(a+b)

 

_qiuhe_=summmer         #变量名一样使用

 

print(_qiuhe_(1,2))          # 3 有返回值时,打印内容

          示例2

                 deffun2():

                    return

                    print('最后一行')            

 

r = fun2()

print(r)               #None  注意return之后的函数语句不再执行

函数的参数传递
1)传递方式:

a)      位置传参

b)      *序列传参

c)       **关键字传参

2)位置传参

     实际参数的对应关系与形式参数的对应关系是以位置来一次对应的

   示例1

          defsum3(a,b,c):

                 returna+b+c

          x= sum3(1,2,3)

          解释: 1实参 对应 a形参

位置传参说明:

          实参和形参通过位置进行对应和传递

          实参和形参的个数必须完全相同

3)序列传参

序列的元素个数必须与列表的个数相同

示例1

def myfun(a,b,c):

   print("a--->",a)

   print("b--->",b)

   print("c--->",c)

 

#位置传参

myfun(1,2,3)

 

#序列传参  字符串,列表,元组

#如果序列所含元素和函数参数个数不对应可以而切片

s1=[4,5,6]

myfun(*s1)

 

s2="ABC"

myfun(*s2)

4)关键字传参

   关键字传参是指传参时,按照形参的名称给形参赋值,实参和形参按照名称进行匹配

   数量必须对应

   defmyfun(a,b,c):

   print("a--->",a)

   print("b--->",b)

   print("c--->",c)

 

#位置传参

myfun(1,2,3)

 

#序列传参  字符串,列表,元组

#如果序列所含元素和函数参数个数不对应可以而切片

s1=[4,5,6]

myfun(*s1)

 

s2="ABC"

myfun(*s2)

 

#关键字传参:

myfun(b=100,a=200,c=700)

5)字典关键字传参

实参和形参通过字典进行传递和匹配,字典的值传递给键对应的形参

说明:

   字典传参的键名和形参名必须一致

   键名必须为字符串

   键名要在形参中存在

示例:

#字典关键字传参  **dict

d = {'a':10,'b':20,'c':30}

myfun(**d)

6)综合传参

四种传参方式,打套组合拳

示例:

def myfun(a,b,c):

   print("a--->",a)

   print("b--->",b)

   print("c--->",c)

 

#综合传参

myfun(*[1], *(200,300))

print()

myfun(100, c=90, b=6)

print()

myfun(100, *(200, 300))

print()

myfun(100, **{'b': 20,'c': 30})

print()

myfun(*(100,), **{'b': 2, 'c': 3})

print()

myfun(*('A'),**{'c': 7}, b=9)

以下是错误 

#位置参数之后不能跟关键字参数

# myfun(c=90,b=6,50)

函数的定义(创建函数或函数形参)
1)函数的缺省参数
(1)语法:

def 函数名(形参1=默认参数1,形参2=默认参数2······)

  语句块

(2)示例:

def  info(name,age=1, addr='不详'):

      print('姓名',name,'年龄',age,'住址',addr)

#调用

info("无所谓", addr="不管")

info("观世音", age=9999999, addr="南海")

info("常侍")

(3)缺省参数说明:

a)    缺省参数必须从右之左依次存在,如果一个参数有缺省值,则其右侧的所有参数都必须有缺省参数(缺省值)

b)    缺省参数可以有0个或1个及以上,甚至全部是缺省参数

(4)错误缺省参数函数

def  fn(a, b=10,c): pass

def  fn(a=1,b, c=5): pass

2) 星号元组形参
(1)语法:

   def函数名(*元组形参名):

          语句块

(2)示例:

 

  

def myfum(*args):

    print("实参个数是", len(args))

    print(args)

for x in args:

 

        print(x)

 

 

myfum(2, 5)

 

执行结果

实参个数是 2

(2, 5)

2

5

 

myfum("100", 200, "Tree", 4.4)

执行结果

实参个数是 4

('100', 200, 'Tree', 4.4)

100

200

Tree

4.4

 

3) 命名关键字形参
(1)语法:

          def  函数名(*,命名关键字形参名):

                  语句块

          或

          def  函数名(*args,命名关键字形参名):

                 语句块

(2)示例:

          示例1:

          defmyfun1(a,b,*,c): #c为命名关键字

                 print(a,b,c)

          myfun1(1,2,c=3)

          myfun1(11,12,33)#错误,必须指明关键字,不能位置传参

 

示例2

 

def myfun2(a,*args,b,c):      #b,c是关键字形参,传参数是只能#按照关键字进行传参

myfun2(1,2,3,4)  #错误

myfun2(1,2,b=3,c=4) #(1,(2,),3,4)

4)双星号字典形参
 (1)语法

   def函数名(**字典形参名)

          语句块

(2)示例

   defmyfun(**kwargs):

      print("参数个数", len(kwargs))

     for k,v in kwargs.items():

       print(k, "--->", v)

 

 

# 调用

myfun(name="tarena", age=15) #dict(**kwagrs)生成非空字典相同

          注意:字典形参的格式,写入一个字典参数{},会报错

执行结果参数个数 2

name ---> tarena

age ---> 15     

5) 函数的参数列表顺序:

   位置形参,缺省参数,星号元组形参,双星号字段形参,命名关键字参数可以混合使用

函数参数自左向右的顺序为

   位置形参,星号元组形参,命名关键字参数,双星号字典形参

例:

   deffn(a,b,*args,c,**kwargs):

          print(a,b,args,c,kwargs)

 fn(1,2,3,4,c=5,name=”tarena”,age=15)

可变/不可变的实参的参数传递区别

可变数据类型(关键在于可增加)

                list  dict set

不可变类型

         float int str ········

1)可变/不可变数据类型区别:

  不可变的类型的数据作为函数参数传入时,函数内部不会改变变量的元数据值,是安全的

  可变类型的数据作为参数穿入时,函数内部可以改变元数据,多用来返回更多数据结果

2)问题

函数只能通过返回值传回数据吗?

不是,还可以通过返回可变数据类型

示例

示例1

l = []

def fn(x):

   x.append(10)

fn(l)

print(l) #结果

示例2

d = {}

def fn(x):

   x["name"] = 'tarena'

 

fn(d)

print(d)   #{'name': 'tarena'}

示例3

t = (1,2,3)

 

def fn(x):

   x[1] = 2.2

 

 

print[t]

fn(t)       #执行报错TypeError: 'tuple'object does not support #    item assignment

print(t)

示例4

t = (1,2,3)

 

def fn2(x):

    x= (4,5,6)

   return x

 

print(t)

 

print(fn2(t))

print(t)

 

函数执行结果:

(1, 2, 3)

(4, 5, 6)

(1, 2, 3)

 

示例5

t = (1,2,3)

 

def fn2(x):

    x= (4,5,6)

 

print(t)

 

print(fn2(t))

print(t) 

执行结果:

(1, 2, 3)

None

(1, 2, 3)

示例6

t = (1, 2, 3)

 

 

def fn2(x):

    x += (4, 5, 6)

    return x

 

 

print(t)

 

print(fn2(t))

print(t)

执行结果

(1, 2, 3)

(1, 2, 3, 4, 5, 6)

(1, 2, 3)

l = [1,2,3]

 

def fn2(x):

    x += [4,5,6]

    x.append([4,5,6])

    return x

 

print(l)

 

print(fn2(l))

print(l)

执行结果

[1, 2, 3]

[1, 2, 3, 4, 5, 6, [4, 5, 6]]

[1, 2, 3, 4, 5, 6, [4, 5, 6]]

l = [1,2,3]

 

def fn2(x):

    x = [4,5,6]

    x.append([4,5,6] )

    x+=[4]

    return x

 

print(l)

print(fn2(l))

print(l)

执行结果

[1, 2, 3]

[4, 5, 6, [4, 5, 6], 4]

[1, 2, 3]

 

 

函数嵌套
1)定义

函数嵌套

是指一个函数里用语句来创建其它函数的情况

函数变量

   函数名是变量,它是创建函数时绑定一个函数

2)函数变量示例:

def fn():

    print("hello")

 

dn = fn

dn()                       #结果 hello

3)嵌套示例:

def fn_order():

   print("外部函数")

 

   def cn_inner():

       print("fn_inner被调用")

 

   cn_inner()

 

 

fn_order()

注意:函数只有调用时才能被执行,如果把cn_inner()这句代码去掉则不会执行内部函数

6函数作为函数的返回值

示例:

def getfn():

   def print_hello():

       print("Hello")

   return print_hello

 

fn=getfn() #fn =print_hello地址 <functiongetfn.<locals>.print_hello at 0x7f45e6747c80> 

fn()                         #fn()    函数名是变量

执行结果

hello

 

 

def getfn():

   def print_hello():

       print("Hello")

   return print_hello()


 

fn=getfn()                      

执行结果:

  Hello

None

 

 

 

 

 

 

 

 

 

 

 

 

 

7函数作为函数的参数传递

   示例

def tab(x, y):

return "|"+x.center(13)+"|"+\

y.center(13)+"|"

 

 

def stri(x, y):

    return "姓名:"+str(x)+'  age:'+str(y)

 

 

def myprint(fx, x, y):

    print(fx(x, y))

 

 

myprint(tab, "tarena", "15")

myprint(tab, "abc", "19")

myprint(stri,"def","24")

myprint(stri,"good","65")

执行结果

|    tarena   |      15     |

|     abc     |      19     |

姓名:def  年龄:24

姓名:good  年龄:65

 

全局变量和局部变量
1)局部变量:

定义在函数内部的变量(包含函数参数)

函数执行时存在,函数执行完后即销毁

2)全局变量:

定义在函数外部,模块内部的变量

一直存在,除非调用del函数

3)示例

v = 100    #全局变量

 

 

def fn():

    v =200  局部变量

    print(v)

fn()

print(v)

 

执行结果

200

100

 v = 100   

 

def fn(v):

    v +=200

    print(v)

fn(v)

print(v)

 

 

执行结果

300

100

def func():

    global v

    v=100

func()

print(v)

 

注意先后顺序

执行结果:

100

 

python作用域
1)作用域定义

也叫名字空间,是变量访问的时候查找变量名的范围空间

2)示例

v = 100   

 

def fn():

    print(v)

fn()

print(v)

执行结果

100

100

先从里面找,找不到往外扩散找

3)四种作用域

局部作用域(函数内) Local  L

外部嵌套函数作用域  Enclosing function locals E

函数定义所在模块(文件)的作用域 全局作用域 Global(module) G

python内置模块的作用域   Builtin(python)B

4)变量名的查找规则

在访问变量时,先查找本地变量,然后是包裹此函数的外部函数的函数内部的变量,之后是全局变量,最后是内置变量

L -------->  E -----------> G  ---------->B

示例

v = 100         #全局作用域G

 

查找

 

def fun1():

    v = 200      #外部嵌套作用域E

    print("fun1.v=", v)

    def fun2():

        v = 300   #局部作用域L

        print("fun2.v=", v)

    fun2()

fun1()

print("v="v)

 

执行结果

fun1.v= 200

fun2.v= 300

v= 100

 

在默认情况下,变量名赋值会创建或者修改本地变量

global 语句
1)定义

告诉解释器,global语句声明的一个或多个变量,这些变量的作用域为模块级的作用域,也称作全局变量

对全局变量(global)的变量赋值将映射到模块文件的内部作用域

对于同一个变量,当global之后其他函数将不需要再声明为全局的,因为已经是全局的了

2)语法:

global 变量1,变量2······

3) 示例

v = 100

 

 

def fn():

    global v     

    v = 200  

print(v)

执行结果

200

如果全局变量不存在执行结果仍不会报错

结果为200

 

4)global说明:

1.全部变量如果要在函数内部被赋值,则必须经过全局声明,否则被认为是局部变量

2.全局变量在函数内部不经过声明就可以访问(前提是变量已经存在)

3.不能先声明局部变量,再用global声明为全局变量,此做法不符合语法规则

4 global变量列表里的变量名不能出现在此作用域的参数列表中,for循环控制目标,类定义,函数定义及import导入名字中

解释第4条示例

def fn(v):                 #参数列表中

    global v

    v = 200

def f3():                   #for循环

    global v

    for v in range(10):

        print(v)

def fr():                   函数定义中

    global fr

 

nonlocal语句
作用

告诉解释器,nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量

2)语法

nonlocal 变量名1,变量2·······

3)示例

var = 100

 

 

def outer():

 

    var = 200

    def inner():

        # nonlocal var

        var += 1

        print("inner.var=", var)

    inner()

    print("outter.var=", var)

 

outer()

 

 

 

 

 

 

 

无nonlocal语句则会报错

UnboundLocalError:

local variable 'var' referenced before assignment

但是去掉var +=1后 print("inner.var=", var)

)语句仍会执行,说明只能访问,不能做任何操作

var = 100

 

 

def outer():

 

    var = 200

比较

    def inner():

        nonlocal var

        var += 1

        print("inner.var=", var)

    inner()

    print("outter.var=", var)

 

outer()

var = 100

 

 

def outer():

 

    var = 200

    def inner():

        # nonlocal var

        print(var +  1)

#未生成新的变量

        print("inner.var=", var)

    inner()

    print("outter.var=", var)

 

outer()

 

 

var = 100

 

 

def outer():

 

    var = 200

    def inner():

#报错 语法错误

 

        # nonlocal var

        print(var +=  1)

                print("inner.var=", var)

    inner()

    print("outter.var=", var)

 

outer()

print(var)

 

 

4)说明

1  nonlocal语句只能在被嵌套函数的内部使用

2 访问nonlocal变量将对外部嵌套函数的作用域内的变量进行操作

3 当有两层或两层以上的函数嵌套时,访问nonlocal变量只对最近一层的变量进行操作

4 nonlocal语句的变量列表里的变量名,不能出现此作用域的参数列表中

nonlocal 和 glocal 区别

var = 100

 

def outer():

    var = 200

    def inner():

        global var

 

        var += 1

    print("inner.var=", var)

    inner()

    print("outter.var=", var)

 

outer()

 

执行结果

101

200

var = 100

 

def outer():

var = 200

def inner():

  nonlocal var

var += 1

        print("inner.var=", var)

    inner()

    print("outter.var=", var)

 

outer()

执行结果

201

201

   一个变量不能既声明为global 又声明 nonlocal

13 lambda 表达式(又称匿名函数对象)
1 作用:

   创建一个匿名(无名)函数对象

同def类似,但不提供函数名

2 语法:

   lambda[参数1,参数2,·····]:表达式

3 示例

 

 

示例1

 

def  myadd(x,y):

          return x+y

以上代码可改写为:

myadd = lambda x, y: x+y

r = myadd(20,70)

print(r)

执行结果:

70

注意:

lambda表达式本身有返回值,利用这个函数直接拿到

 

示例2

print(‘100*200=’,(lambda x,y:x*y)(100*200))

 

示例3

 

def op(fn, x, y):

    return(fn(x, y))

 

 

print(  op( (lambda x, y: x + y )   , 100, 200)  )  返回值是300

 

print(  op( (lambda x, y: x * y )   , 100, 200)  ) 返回值是20000

4 语法说明

A. lambda表达式只是一个表达式,它用来创建一个函数对象

B. 当lambda表达式执行时,返回的是冒号(:)后表达式的值

C.  lambda表达式创建的函数只能包含单条语句

D. lambda比函数简单且可以随时创建和销毁,有利于较少程序的耦合度

5 练习

def mymax(x,y):

    if x>y:

        return x

    else:

        return y

mymax2 = lambda x,y: x if x>y else y

 

 

函数

mymax2 = lambda x,y: max(x,y)

 

 

print(mymax(100,200))

print(mymax2(100,200))

 

执行结果

200

200

 

14 globals(),locals()函数

globals()返回当前全局作用域内变量的字典

locals()返回当前局部作用域内的变量的字典

这两个函数为作用域为模块级

示例

a =1

b = 2

def fn(c,d):

    e = 300

    print("locals返回:",locals())

    print("globals返回:",globals())

 

fn(10,20)

 

执行结果

locals返回: {'d': 20, 'c': 10, 'e': 300}

globals返回: {'__name__': '__main__', '__spec__': None, '__file__': 'day11ktlx2.py', '__cached__': None, 'fn': <function fn at 0x7fcefe9acf28>, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fcefe973898>, 'b': 2, '__package__': None, 'a': 1, '__doc__': None, '__builtins__': <module 'builtins' (built-in)>}

15 eval(),exec()函数
1)eval()函数作用:

  把一个字符串当成一个表达式来执行,返回表达式执行后的结果

eval()格式:

  eval(source,global=None,locals=None)

2)示例

x=1

y=2

a = eval("x+y")

print(a)

 

 

local_scope={"x":4,"y":5}         #“字典”

a = eval("x*y",local_scope)       #无None

print(a)

 

local_scope={"x":4,"y":5}

a = eval("x*y",None,local_scope)

print(a)

3)exec()函数

(1)作用:

   把一个字符串当做执行程序来执行

(2)格式:

   exec(source,globals=None,locals=None)

注意:glocals,locals的作用同eval

(3)示例  有些不准确

x =11

y=22

print("hello:",x,y)

 

 

 

16 闭包 closure

   closure[‘kl əu ʒ ə]

1)定义

   将组成函数的语句和这些语句的执行环境打包在一起时,得到的对象成为闭包

闭包是一种特殊的函数

2)说明:

如果一个内嵌函数访问函数外部作用域中的变量,则这个函数就是闭包

3)示例

 

 

闭包

def make_power(x):

    def fn(org):

        return org ** x

    return fn

r = make_power(20)

n =r(10)

print(n)

 

灵活使用

执行结果

100000000000000000000  10**20

17 函数式编程

  是指用一系列函数解决问题

函数是一等公民

1)函数式编程的好处:

(1)每一个函数完成细小的功能,一系列函数的任意组合可以完成大问题。

(2)函数仅接收输入并产生输出,不包含任何可能影响输出的内部状态

18 函数的可重入性

   是指输入一定,则输出必然一定

1)示例

 

不可重入式函数

可重入式函数

y = 20

 

 

def myadd(x):

    return x + y

print(myadd(10))

 

y = 30

print(myadd(10))

def mysum(x,y):

return x+y

 

 

函数不调用函数外的变量

2)优点:

易于测试

易于调试

更高的生产率

模块化

逻辑可证

19 高阶函数
1)定义

什么是高阶函数

满足下列条件中一个的函数即为高阶函数:

1 函数接受一个或多个函数作为参数传入

 2    函数返回一个函数

2)python内置(builtins)高阶函数

(1)map (生成一个迭代器)

(2)filter(返回还是原来数据类型

(3)sorted(生成一个列表)使用快速排序

3) map函数:
(1)定义

map(func,*iterable(序列传参))用函数和可迭代对象中的每一个元素作为参数计算出新的可迭代对象,当最短的一个可迭代对象完成迭代后,此迭代生成结束

(2)示例

  

示例1

def func(x):

          return x**2

#生成一个迭代器,此迭代器可以生成一个1~9的自然数的平方

mit = map(func,range(1,10))

for x in mit:

          print(x,end=" ")

执行结果

1 4 9 16 25 36 49 64 81

示例2

#生成一个迭代器,此迭代器可以生成 1*4,2*3,3*2,4*1

def mymul(x,y): #两个参数,两个可迭代对象

    return x*y

 

mit = map(mymul,[1,2,3,4],[4,3,2,1])

for x in mit:

    print(x,end=" ")

执行结果

4 6 6 4

示例3

#求出1**1+2**2+3**3·····

n = int(input("请输入数值"))

s = sum(map(pow,range(1,n+1),range(1,n+1)))

print(s)

输入数为3

执行结果为32

s1=sum(map(lambda x:pow(x,x),range(1,n+1)))

4)filter函数
 (1)语法: 

filter(function or None,iterable)

(2)作用:

筛选序列中的数据,返回一个可迭代对象,此可迭代对象将对iterable进行筛选

(3)说明:

function将对iterable中 每个元素进行求值,返回false则将此数据丢弃,返回True则保留此数据,还是原来的数据类型

(4)示例:

l = [x for x in range(10)]

print(l)

 

 

def isold(x):      #返回是Ture or False,这样才能满足fiter中函数#的要求

    return x % 2 == 1

l2 = [x for x in filter(isold, range(10))]

 

print(l2)

 

执行结果

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[1, 3, 5, 7, 9]

 

5)sorted函数
(1)格式:

   sorted(iterable,key=None,reverse=False)  默认升序

(2)作用:

将原可迭代对象的数据进行排序,生成排序后的列表

(3)说明:

   key函数用来提供一个值,这个值将作为排序的依据

 

(4)示例

示例1

l = [5,7,3,1,-2,-9]

l2 = sorted(l)

print(l2)

#[-9,-2,1,3,5,7]

l2=sorted(l,reverse=True)#降序

 

print(l2)

#[7, 5, 3, 1, -2, -9]

 

 

l2 = sorted(l,key=abs,reverse=True)

print(l2)

#[-9, 7, 5, 3, -2, 1]

 

 

示例2

names = ['Tom', 'Jerry', 'Spike', 'Tyke']

name1 = sorted(names)

 

print(name1)

# ['Jerry', 'Spike', 'Tom', 'Tyke']

 

name2 = sorted(names, key=len)

print(name2)

#['Tom', 'Tyke', 'Jerry', 'Spike']

 

def k(x):

return x[::-1]  #此函数可以写成lambda表达式

 

name3 = sorted(names,key=k) #翻转后排序

   

print(name3)

#['Spike', 'Tyke', 'Tom', 'Jerry']

 

name4 = sorted(names,key=(lambda x:x[::-1]))

print(name4)

# ['Spike', 'Tyke', 'Tom', 'Jerry']

 

20 递归函数 recursion [ri’ kə: ʃn]  栈的模型
1)定义

函数直接或者间接的调用自身

注意:使用递归函数之前必须考虑好递归函数的出口,编写时也要把出口代码,写在最前端

2)示例

def f():

    print("hello")

    f()

 

 

f()

print("递归完成")

3)说明

递归一定要控制递归的层数,当符合某一条件时要终止递归调用几乎所有的对都能用while循环来代替

4)优缺点

 优点:可以把问题简化,可以让思路更清晰,代码更简洁

缺点:递归因系统环境影响大,当递归深度太大时,可能会得到不可预知的结果

def myfac(n):

    if n == 1:

        return 1

    return n * myfac(n-1)

 

 

print(myfac(5))

执行结果

120

示例2

def myfun(n):

    if n==0:

        return

    print("hello")

    time.sleep(1)

    myfun(n-1)

 

myfun(2)

 

每隔一秒钟打印一个hello,共打印n次

 

 

5) 递归的用途:

   文件查找

   扫雷游戏

   ·······

21 装饰器

   decorator(专业提高篇) [‘d e k ə r ei t ə]

decorator decorator decorator detorator

1)定义

装饰器是一个函数

2)作用:

是用来包装另一个函数或类

3)包装的目的

   包装的目的是在不改变原有函数名的情况下,改变被包装函数(对象)的行为

4)装饰器函数
(1)语法:

def 装饰器函数名(参数):

          函数块

          return函数

改变被装饰函数的绑定关系

(2)示例

def deco(fn):   #fucntionName

    print("装饰器函数被调用,并返回原函数")

    return fn

5)带装饰器函数语法:

@装饰器函数名[(装饰器函数传参)]<换行>

def 函数名(参数列表)

          语句块

解释:[]可省略

 

示例

def deco(fn):  # fucntionName

    print("装饰器函数被调用,并返回原函数")

    return fn

 

@deco

def myfunc():

print("函数myfunc被调用")

 

 

myfunc()

myfunc()

 

注意:装饰器被调用一次原因是:@deco等共同此语句

      也就是说,并不是函数代用此方法

# 先执行装饰器函数,其实执行的是语句[myfunc=deco(myfunc)],如果更换装饰器函数的返回值,则myfunc会绑定到新的函数上

 

 

执行结果

 

>>>>>>装饰器函数被调用,并返回原函数

>>>>>>>函数myfunc被调用

>>>>>>>函数myfunc被调用

 

 

 

用法1

def deco(fn):  # fucntionName

    print(">>>>>>装饰器函数被调用,并返回原函数")

    return lambda : print('>>>>>>>,Hello world')

 

@deco

def myfunc():

    print(">>>>>>>函数myfunc被调用")

 

myfunc()

 

执行结果

>>>>>>装饰器函数被调用,并返回原函数

>>>>>>>,Hello world

 

用法2

def noteWarn(fn):

    def saveM1(name, x):

        print("欢迎", name, '来xx银行办理业务')

        fn(name, x)  # 闭包

        print('业务已经办理成功')

    return saveM1

 

 

@noteWarn 

 #sameM = noteWarn(sameM),notewarn里面的saveM1第一次不会被执行,而是返回一个saveM1函数名,即saveM=saveM1

def saveM(name, x):

    print("name", '存入', x, '元')

#开始执行saveM1函数

#注意:写装饰器的规律,执行的新的逻辑要包括在装饰器内

  比切面编程难理解一点

saveM('小张', 200)

saveM('小赵', 500)

 

def decorator(fn):

    def wanshanyiqiandaima():

        fn()

    return wanshanyiqiandaima

@decorator(qichuhanshu=decorator(qichuhanshu))

def qichuhanshu():

    code modual

22 函数的文档字符串
1)语法

def 函数名(参数列表):

          “函数解释字符串”

          语句块

2)说明:

   文档字符串通常用来说明函数的功能和用法

 用>>>help(函数名)  可以查看文档说明

但是这个新建函数必须在交互模式执行过后才能用help(函数名)命令行

3)示例

def mymax(x, w):

'''mymax函数用来取x和w最大值

x是形参

w也是形参

'''

pass

注意:这个字符串不是注释,只有#开头的才是字符串

     

 

23 已学函数的语法:

[@函数装饰器]

def 函数名([位置参数],[*元组形参],[命名关键字参数],[字典关键字参数]):

   文档注释

语句块(包含闭包)

[]代表可以省略

24 函数的属性:
1)__name__ 属性
(1)作用:

用来记录函数名

(2)说明:

   以双下划线开头,以双下划线结尾的标识符,通常代表python的特殊属性等

(3)示例

         

def abc():

    pass

 

a = abc

print(a.__name__)  # 属性

print(abc.__name__)

执行结果

abc

abc

 

可以知道最终绑定的函数是哪一个(用法之一)

 

2) __doc__属性

用来记录文档字符串

1)示例

 

def des():

    '自学能力,自学时间'

 

    pass

print(des.__doc__)

 

 

25 函数的重命名
1示例

def xxx():

    pass

 

yyy = xxx

# xxx = lambda : True

 

def aaa():

    pass

 

xxx=aaa

 

 

print(yyy.__name__)

print(xxx.__name__)

 

执行结果

xxx

aaa

警示:绑定

匿名函数的的函数名,统一为lambda

 

十 模块module


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值