Python函数、装饰器(基础整理)

来源:互联网 发布:软件维护是指 编辑:程序博客网 时间:2024/05/23 22:27

本文是复习笔记,参考听课内容和伯乐在线技术文。

局部作用域v.s.全局作用域

a_string = "This is a global variable"def foo():    a_string = "test" # 1    print(locals())foo()   #{'a_string': 'test'}a_string # 2   #'This is a global variable'#全部变量可以被访问(如果是可变类型,甚至可以被修改)但是(默认)不能被赋值。在函数 #1 处,实际上是创建了一个和全局变量相同名字的局部变量,并且“覆盖”了全局变量。通过在函数 foo 中打印局部命名空间可以印证这一点,并且发现局部命名空间有了一项数据。在 #2 处的输出可以看到,全局命名空间里变量 a_string 的值并没有改变。

函数参数

位置参数
关键字参数
*位置参数包裹:解包裹成位置参数
** 关键字参数包裹:解包裹成关键字参数
定义时元组/字典包裹,调用函数时传入元组列表/字典解包

def foo(x, y=0): # 1    return x - yfoo(3, 1) # 2foo(3) # 3foo() # 4 TypeError: foo() takes at least 1 argument (0 given)foo(y=1,x=3) # 5foo(y=5,4) # 6 positional argument follows keyword argument
def sum1(*tup):    for i in range(len(tup)):        print(tup[i])    return max(tup)l1=[1,2,53,43]sum1(*l1)
def score(**dic):    print(type(dic))    for k,v in dic.items():        print(k,v)#score(啊=1,哦=2)dd={'a':1,'b':2,'c':3}score(**dd)

函数对象,参数是函数

#在 Python 中函数只是常规的值,就像其他任意类型的值一样。这意味着可以将函数当做实参传递给函数,或者在函数中将函数作为返回值返回。def foo():passfoo.__class__ # 1 functionissubclass(foo.__class__, object)#函数也是对象#issubclass(int, object)def add(x, y):    return x + ydef sub(x, y):    return x - ydef apply(func, x, y): # 1    return func(x, y) # 2apply(add, 2, 1) # 3#在 #1 处可以看到变量接收一个就像其他普通变量一样的函数。在 #2 处调用了传递给 apply 的函数 fun——在 Python 中(双括号是调用操作符),调用变量名包含的值。在 #3 处展示了在 Python 中把函数作为值传参。

函数是返回值,()调用操作符

def outer():    def inner():        print("Inside inner")    return inner # 1foo = outer() #2foo   # <function __main__.outer.<locals>.inner>foo()   #Inside inner#在 #2 处将获得返回值即函数 inner,并赋值给新变量 foo。可以看到如果鉴定 foo,它确实包含函数 inner,通过使用(调用操作符)来调用它。

闭包:函数记住其外层作用域的事实

def outer(x):    def inner():        print(x) # 1    return innerprint1 = outer(1)print2 = outer(2)print1()   #return: 1print2()   #return: 2#闭包——函数记住其外层作用域的事实——可以用来构建本质上有一个硬编码参数的自定义函数。虽然没有直接给 inner 函数传参 1 或 2,但构建了能“记住”该打印什么数的 inner 函数自定义版本。Python 支持一种名为函数闭包的特性,意味着在非全局作用域定义的 inner 函数在定义时(记得外层命名空间)是怎样的。inner 函数包含了外层作用域变量,通过查看它的 func_closure 属性可以看出这种函数闭包特性。

高阶函数

该函数的参数可以接收指向函数对象的函数,另一个参数是可迭代对象
格式:funname(fun,inter)

#自己写的高阶函数maxfdef maxf(sum,lis):return sum(lis)maxf(sum,[1,2,3,4])
#python内置的高阶函数filter,map,reducedef dele(score):    if score>=60:        return True    else:        return Falselist(filter(dele,[100,55,70]))list(filter(dele,(99,55,43,65)))
from functools import reduce  #两两操作reduce(lambda a,b:max(a,b),(33,23,44,55))
list(map(lambda x:x**2,[1,4,0]))  #一一映射

匿名函数

foo=lambda a,b,c:max(a,b,c)type(foo)foo(3,4,5)
d1={'china':15,'India':9,'USA':2,'Japan':1.5}sorted(d1.items(),key=lambda x:(x[0],x[1]))

偏函数

import functoolshex2int2=functools.partial(int,base=16)hex2int2('5')hex2int2('F')

装饰器

用一个包装的函数,替换包含函数的变量,实现装饰函数
使用装饰器很简单!虽说写类似 staticmethod 或者 classmethod 的实用装饰器比较难,但用起来仅仅需要在函数前添加 @装饰器名 即可!

def outer(some_func):    def inner():        print("before some_func")        ret = some_func() # 1        return ret + 1    return innerdef foo():    return 1decorated = outer(foo) # 2decorated()#outer的参数是foo,返回inner赋给decorated,decorated()就是inner(),调用inner函数,此时由于闭包结构,inner函数记住了外部some_func=foo#打印“before some_func”,ret=foo(),foo()返回1,所以ret=1,最终返回2#变量 decorated 是 foo 的装饰版——即 foo 加上一些东西。#事实上,如果写了一个实用的装饰器,可能会想用装饰版来代替 foo,这样就总能得到“附带其他东西”的 foo 版本。foo=outer(foo)foo()   #现在任意调用 foo() 都不会得到原来的 foo,而是新的装饰器版!
import datetimedef extrafoo(func):    def inner():        print('extra:',datetime.datetime.now())        print('from inner to execute:',func.__name__)        print('the',func.__name__,'result:',func())    return innerdef foo1():    return 'this is foo1 function--'foo1=extrafoo(foo1)   #在foo1外包裹了一层extrafoo作用,再调用foo1就不是原来简单定义的foo1了,而是extrafoo(foo1)foo1()
import datetimedef extrafoo(func):    def inner():        print('extra:',datetime.datetime.now())        print('from inner to execute:',func.__name__)        print('the',func.__name__,'result:',func())    return inner@extrafoodef foo1():    return 'this is foo1 function--'foo1()
原创粉丝点击