Python学习笔记-2017.5.4thon学习笔记-2017.5.10

本笔记记录学习Python过程中的学习心得:

本次主要记录内容:

Python装饰器部分。

Python装饰器是一种特殊的函数,可以为其他函数添加新功能,并遵循以下两种规则:

1、不修改原来的函数代码内容;

2、不修改原来函数的调用方式。

原理通过以下方式来实现:

高阶函数+嵌套函数=Python装饰器。

其中嵌套函数定义示例如下:

def test1():
    pass
    def test2():
        pass

 在使用def定义函数后,在函数内部继续使用def定义函数,称之为嵌套函数。

如下使用方式,不是嵌套函数,只是函数的调用:

def test2():
    pass
def test1():
    test2()

 高阶函数的定义:

1、使用函数的名字当做实参传入其他函数;

2、函数的返回值是函数的名字。

以上两个定义举例说明:

一、使用函数的名字当做实参传入其他函数:

def test2():
    print("in the test2")
def test1(xxx):
    print(xxx)
test1(test2)

 如上调用test1时,test2作为实参传入test1,形参为xxx,其中test2如果写为test2()形式,那传入的是test2函数的执行返回值,如上,test2形式传入的是test2的内存地址,因此print的结果,也是test2的内存地址。

二、函数的返回值是函数的名字

def test2():
    print("in the test2")
def test1(xxx):
    return xxx
test1(test2)

 上边的函数,直接将test2的内存地址当做返回值进行return。

如上是高阶函数和嵌套函数的学习和介绍,下面是它们的使用场景,以举例说明。

1、高阶函数,函数名作为实参

def bar():
    time.sleep(1)
    print("in the bar")
bar()

 添加一个函数,获取bar函数的运行时间,因此获得如下函数

_Author_ = "Jack"
import time

def foo(func):
    starttime=time.time()
    func()
    stoptime=time.time()
    print("foo run time is %s" %(stoptime-starttime))
def bar():
    time.sleep(1)
    print("in the bar")

foo(bar)

如上代码,其中foo作为一个函数,装饰了bar函数,没有修改bar函数的原代码,但是修改了函数的调用方式。

2、返回值为函数名:

初始代码:

def bar():
    time.sleep(1)
    print("in the bar")
bar()

 修改后代码:

_Author_ = "Jack"
import time

def foo(func):
    return func
def bar():
    time.sleep(1)
    print("in the bar")
bar = foo(bar)
bar()

 如上代码,没有修改调用方式,但是没有实现装饰功能,上述原理为:bar作为变量传入foo函数,func=bar,foo函数return func,即为return bar的内存地址,bar= foo(bar),将原先的bar进行覆盖;

装饰器示例,如上进行组合,可以形成装饰器,装饰器完整示例:

初始代码:

def bar():
    time.sleep(1)
    print("in the bar")
bar()

 加入装饰器后的代码(timer(bar)函数,返回值是foo函数的地址,因此bar=timer(bar),等于bar=foo,bar()=foo(),而foo函数就是运行原先的bar函数,并统计时间。):

_Author_ = "Jack"
import time

def timer(func):
    def foo():
        starttime=time.time()
        func()
        stoptime=time.time()
        print("foo run time is %s" %(stoptime-starttime))
    return foo
def bar():
    time.sleep(1)
    print("in the bar")

bar = timer(bar)#可修改,修改为在bar函数前面加入@timer
bar()

 如上代码,即为,bar=foo,因此如果存在变量,可以在foo()中加入变量,效果如下:

_Author_ = "Jack"
import time

def timer(func):
    def foo(*args,**kwargs):
        starttime=time.time()
        func(*args,**kwargs)
        stoptime=time.time()
        print("foo run time is %s" %(stoptime-starttime))
    return foo
@timer #bar = timer(bar)
def bar(xxx): time.sleep(1) print("in the bar",xxx) bar("Jack")

 使用*args和**kwargs的原因是,装饰器函数通常装饰很多函数,因此,变量个数不固定,有可能没有,也有可能很多,因此采用这种方式。

练习版本:

_Author_ = "Jack"

user,passwd = "jack", "123456"
def authentication(func):
    def wrapper():
        userinput = input("Username:").strip()
        password = input("Password:").strip()
        if userinput == user and password == passwd:
            print("autentication success!")
            return func()
        else:
            exit("authentication failed,invailid username or password!")
    return wrapper
def index():
    print("welcome to index page!")
@authentication
def home():
    print("wel come to home page!")
    return "xxxxxxxxxxxx"
@authentication
def bbs():
    print("welcome to bbs page!")

index()
print(home())
bbs()

 传入参数练习如下:

_Author_ = "Jack"

user,passwd = "jack", "123456"
def authentication(func):
    def wrapper(*args,**kwargs):
        userinput = input("Username:").strip()
        password = input("Password:").strip()
        if userinput == user and password == passwd:
            print("autentication success!")
            func(*args,**kwargs)
        else:
            exit("authentication failed,invailid username or password!")
    return wrapper
def index():
    print("welcome to index page!")
@authentication
def home(name):
    print("wel come to home page!%s" %name)
@authentication
def bbs():
    print("welcome to bbs page!")
index()
home("Steven")
bbs()

 装饰器带有参数版本,因此,使用三层嵌套函数的办法,装饰器参数在第一层,原来的装饰器参数在第二层(即传入函数名字的参数),函数自带参数在第三层(即原函数自带参数):

_Author_ = "Jack"

user,passwd = "jack", "123456"
def authentication(auth_type):
    print("auth_type", auth_type)
    def out(func):
        def wrapper(*args,**kwargs):
            userinput = input("Username:").strip()
            password = input("Password:").strip()
            if userinput == user and password == passwd:
                print("autentication success!")
                func(*args,**kwargs)
            else:
                exit("authentication failed,invailid username or password!")
        return wrapper
    return out
def index():
    print("welcome to index page!")
@authentication(auth_type="local")
def home(name):
    print("wel come to home page!%s" %name)
@authentication(auth_type="ldap")
def bbs():
    print("welcome to bbs page!")
index()
home("Steven")
bbs()

 

posted @ 2017-05-10 21:51  万青  阅读(184)  评论(0)    收藏  举报