zoukankan      html  css  js  c++  java
  • 函数闭包与装饰器

    # 统计函数的执行时间
    import time
    def cal(l):
        start_time=time.time()        #加入1
        res=0
        for i in l:
            time.sleep(0.1)
            res+=i
        stop_time = time.time()        #加入2
        print('函数的运行时间是%s' %(stop_time-start_time))
        return res
    #如果函数是线上运行的,那修改源代码违反开放封闭式原则。因为别的可能还在调用它。
    
    print(cal(range(100)))
    
    def index():
        pass
    
    def home():
        pass

    一 什么是装饰器

    装饰器即函数

    装饰即修饰,意指为其他函数添加新功能

    装饰器定义:本质就是函数,功能是为其他函数添加新功能

    二 装饰器需要遵循的原则

    1.不修改被装饰函数的源代码(开放封闭原则)

    2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式

    三 实现装饰器知识储备

    装饰器=高阶函数+函数嵌套+闭包

    四 高阶函数

    高阶函数定义:
    1.函数接收的参数是一个函数名

    2.函数的返回值是一个函数名

    3.满足上述条件任意一个,都可称之为高阶函数

    #1、函数接收的参数是一个函数名:保证函数源代码不被修改
    import time
    def foo():
        time.sleep(3)
        print('你好啊林师傅')
    
    def test(func):                    #test形参接收了函数名,为高阶函数。func为函数的内存地址
        # print(func)                    #打印出来的是内存地址
        start_time=time.time()
        func()                        #直接运行foo函数
        stop_time = time.time()
        print('函数运行时间是  %s' % (stop_time-start_time))
    # foo()
    test(foo)
    
    # 2、高阶函数的返回值也是一个函数名,函数的调用方式也不用修改了
    def foo():
        print('from the foo')
    def test(func):
        return func        
    
    res=test(foo)        #从而func就是foo内存地址
    # print(res)
    res()                #函数直接就运行了
    
    #进一步取消res,就用原来的foo名字
    foo=test(foo)
    # # print(res)
    foo()                # 不改变函数调用方式
    
    
    
    #########整合版本1
    import time
    def foo():
        time.sleep(3)
        print('来自foo')
    
    #不修改foo源代码
    #不修改foo调用方式
    #多运行了一次,不合格
    def timer(func):         #参数为函数名
        start_time=time.time()
        func()                #return func如果换到这里来,并没有给原函数添加任何功能。
        stop_time = time.time()
        print('函数运行时间是  %s' % (stop_time-start_time))
        return func             #返回值为函数名
    foo=timer(foo)             #赋给foo,执行了一遍
    foo()                     #直接调用foo,又执行了一遍foo。只能改return
    ##结果:
    来自foo
    函数运行时间是 3.0001756482365
    来自foo    #多打印了一个
    #高阶函数没办法正常运行且顺利添加新功能
    #1、函数接收的参数是一个函数名:保证函数源代码不被修改
    import time
    def foo():
        time.sleep(3)
        print('你好啊林师傅')
    
    def test(func):                    #test形参接收了函数名,为高阶函数。func为函数的内存地址
        # print(func)                    #打印出来的是内存地址
        start_time=time.time()
        func()                        #直接运行foo函数
        stop_time = time.time()
        print('函数运行时间是  %s' % (stop_time-start_time))
    # foo()
    test(foo)
    
    # 2、高阶函数的返回值也是一个函数名,函数的调用方式也不用修改了
    def foo():
        print('from the foo')
    def test(func):
        return func        
    
    res=test(foo)        #从而func就是foo内存地址
    # print(res)
    res()                #函数直接就运行了
    
    #进一步取消res,就用原来的foo名字
    foo=test(foo)
    # # print(res)
    foo()                # 不改变函数调用方式
    
    
    
    #########整合版本1
    import time
    def foo():
        time.sleep(3)
        print('来自foo')
    
    #不修改foo源代码
    #不修改foo调用方式
    #多运行了一次,不合格
    def timer(func):         #参数为函数名
        start_time=time.time()
        func()                #return func如果换到这里来,并没有给原函数添加任何功能。
        stop_time = time.time()
        print('函数运行时间是  %s' % (stop_time-start_time))
        return func             #返回值为函数名
    foo=timer(foo)             #赋给foo,执行了一遍
    foo()                     #直接调用foo,又执行了一遍foo。只能改return
    ##结果:
    来自foo
    函数运行时间是 3.0001756482365
    来自foo    #多打印了一个
    #高阶函数没办法正常运行且顺利添加新功能
    #1、函数接收的参数是一个函数名:保证函数源代码不被修改
    import time
    def foo():
        time.sleep(3)
        print('你好啊林师傅')
    
    def test(func):                    #test形参接收了函数名,为高阶函数。func为函数的内存地址
        # print(func)                    #打印出来的是内存地址
        start_time=time.time()
        func()                        #直接运行foo函数
        stop_time = time.time()
        print('函数运行时间是  %s' % (stop_time-start_time))
    # foo()
    test(foo)
    
    # 2、高阶函数的返回值也是一个函数名,函数的调用方式也不用修改了
    def foo():
        print('from the foo')
    def test(func):
        return func        
    
    res=test(foo)        #从而func就是foo内存地址
    # print(res)
    res()                #函数直接就运行了
    
    #进一步取消res,就用原来的foo名字
    foo=test(foo)
    # # print(res)
    foo()                # 不改变函数调用方式
    
    
    
    #########整合版本1
    import time
    def foo():
        time.sleep(3)
        print('来自foo')
    
    #不修改foo源代码
    #不修改foo调用方式
    #多运行了一次,不合格
    def timer(func):         #参数为函数名
        start_time=time.time()
        func()                #return func如果换到这里来,并没有给原函数添加任何功能。
        stop_time = time.time()
        print('函数运行时间是  %s' % (stop_time-start_time))
        return func             #返回值为函数名
    foo=timer(foo)             #赋给foo,执行了一遍
    foo()                     #直接调用foo,又执行了一遍foo。只能改return
    ##结果:
    来自foo
    函数运行时间是 3.0001756482365
    来自foo    #多打印了一个
    #高阶函数没办法正常运行且顺利添加新功能
    #1、函数接收的参数是一个函数名:保证函数源代码不被修改
    import time
    def foo():
        time.sleep(3)
        print('你好啊林师傅')
    
    def test(func):                    #test形参接收了函数名,为高阶函数。func为函数的内存地址
        # print(func)                    #打印出来的是内存地址
        start_time=time.time()
        func()                        #直接运行foo函数
        stop_time = time.time()
        print('函数运行时间是  %s' % (stop_time-start_time))
    # foo()
    test(foo)
    
    # 2、高阶函数的返回值也是一个函数名,函数的调用方式也不用修改了
    def foo():
        print('from the foo')
    def test(func):
        return func        
    
    res=test(foo)        #从而func就是foo内存地址
    # print(res)
    res()                #函数直接就运行了
    
    #进一步取消res,就用原来的foo名字
    foo=test(foo)
    # # print(res)
    foo()                # 不改变函数调用方式
    
    
    
    #########整合版本1
    import time
    def foo():
        time.sleep(3)
        print('来自foo')
    
    #不修改foo源代码
    #不修改foo调用方式
    #多运行了一次,不合格
    def timer(func):         #参数为函数名
        start_time=time.time()
        func()                #return func如果换到这里来,并没有给原函数添加任何功能。
        stop_time = time.time()
        print('函数运行时间是  %s' % (stop_time-start_time))
        return func             #返回值为函数名
    foo=timer(foo)             #赋给foo,执行了一遍
    foo()                     #直接调用foo,又执行了一遍foo。只能改return
    ##结果:
    来自foo
    函数运行时间是 3.0001756482365
    来自foo    #多打印了一个
    #高阶函数没办法正常运行且顺利添加新功能
    #1、函数接收的参数是一个函数名:保证函数源代码不被修改
    import time
    def foo():
        time.sleep(3)
        print('你好啊林师傅')
    
    def test(func):                    #test形参接收了函数名,为高阶函数。func为函数的内存地址
        # print(func)                    #打印出来的是内存地址
        start_time=time.time()
        func()                        #直接运行foo函数
        stop_time = time.time()
        print('函数运行时间是  %s' % (stop_time-start_time))
    # foo()
    test(foo)
    
    # 2、高阶函数的返回值也是一个函数名,函数的调用方式也不用修改了
    def foo():
        print('from the foo')
    def test(func):
        return func        
    
    res=test(foo)        #从而func就是foo内存地址
    # print(res)
    res()                #函数直接就运行了
    
    #进一步取消res,就用原来的foo名字
    foo=test(foo)
    # # print(res)
    foo()                # 不改变函数调用方式
    
    #########整合版本1
    import time
    def foo():
        time.sleep(3)
        print('来自foo')
    
    #不修改foo源代码
    #不修改foo调用方式
    #多运行了一次,不合格
    def timer(func):         #参数为函数名
        start_time=time.time()
        func()                
        stop_time = time.time()
        print('函数运行时间是  %s' % (stop_time-start_time))
        return func             #返回值为函数名
    foo=timer(foo)             #赋给foo,执行了一遍
    foo()                     #直接调用foo,又执行了一遍foo。只能改return
    ##结果:
    来自foo
    函数运行时间是 3.0001756482365
    来自foo    #多打印了一个
    #高阶函数没办法正常运行且顺利添加新功能

    #没有修改被修饰函数的源代码,也没有修改被修饰函数的调用方式,但是也没有为被修饰函数添加新功能
    def timer(func):
    start_time=time.time()
    return func #return func如果换到这里来,并没有给原函数添加任何功能。
    stop_time = time.time()
    print('函数运行时间是 %s' % (stop_time-start_time)

    foo=timer(foo)
    foo()

    
    
    #高阶函数应用1:把函数当做参数传给高阶函数
    import time
    def foo():
        print('from the foo')
    
    def timmer(func):
        start_time=time.time()
        func()
        stop_time=time.time()
        print('函数%s 运行时间是%s' %(func,stop_time-start_time))
    timmer(foo)
    #总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式
    #高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名
    import time
    def foo():
        print('from the foo')
    
    def timmer(func):
        start_time=time.time()
        return func
        stop_time=time.time()
        print('函数%s 运行时间是%s' %(func,stop_time-start_time))
    foo=timmer(foo)
    foo()
    #总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能

    高阶函数总结
    1.函数接收的参数是一个函数名
      作用:在不修改函数源代码的前提下,为函数添加新功能,
      不足:会改变函数的调用方式
    2.函数的返回值是一个函数名
      作用:不修改函数的调用方式
      不足:不能添加新功能

    五 函数嵌套

    # 函数嵌套:在一个函数中重新定义一个新的函数
    def foo():
        print('from foo')
        def test():
            pass
    
    def father(auth_type):
        # print('from father %s' %name)
        def son():
            # name='linhaifeng_1'
            # print('我的爸爸是%s' %name)
            def grandson():
                print('我的爷爷是%s' %auth_type)    #在上上级找,在最外层传,这里也能收到
            grandson()            #运行函数
        # print(locals())        #打印当前层的局部变量:name,son函数也是
        son()
    # father('linhaifeng')
    father('filedb')
    六 闭包
     1 '''
     2 闭包:在一个作用域里放入定义变量,相当于打了一个包
     3 '''
     4 def father(name):
     5     def son():
     6         # name='alex'
     7         print('我爸爸是 [%s]' %name)
     8         def grandson():
     9             # name='wupeiqi'
    10             print('我爷爷是 [%s]' %name)
    11         grandson()
    12     son()
    13 
    14 father('林海峰')
    #装饰器实现
    import
    time def timmer(func): #func=test def wrapper(): # print(func) start_time=time.time() func() #就是在运行test() stop_time = time.time() print('运行时间是%s' %(stop_time-start_time)) return wrapper @timmer #test=timmer(test) def test(): time.sleep(3) print('test函数运行完毕') test() res=timmer(test) #返回的是wrapper的地址 res() #执行的是wrapper() test=timmer(test) #返回的是wrapper的地址 test() #执行的是wrapper() @timmer 就相当于 test=timmer(test)

    七 无参装饰器

    #补充知识:用解压的方式取出一个列表的最开头和结尾
    #比索引略微简洁一些,有的时候适用
    #例1:
    a,b,c='hel'
    >>>a
    'h'
    >>>b
    'e'
    >>>c
    'l'
    #例2:a表示列表第一个,c表示最后一个
    l=[0,2,3,445,67,8,9,92,2,1]
    >>>a.*_.c=l       #下划线表示中间所有元素的变量名,可以随便起,*m也可以
    >>>a    
    '0'
    >>>c
    '1'        
    #例3:取出头尾两个
    >>>a,b.*_.c,d=l 
    #对比索引:a,d=l[0],l[-1]

    无参装饰器=高级函数+函数嵌套

    基本框架

    1 #这就是一个实现一个装饰器最基本的架子
    2 def timer(func):      #func就相当于你输入的test函数
    3     def wrapper():
    4      print(func)   #函数嵌套 4 func() 5 return wrapper

    加上参数

    1 def timer(func):
    2     def wrapper(*args,**kwargs):
    3         func(*args,**kwargs)
    4     return wrapper

    加上功能

    1 import time
    2 def timer(func):
    3     def wrapper(*args,**kwargs):
    4         start_time=time.time()
    5         func(*args,**kwargs)
    6         stop_time=time.time()
    7         print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time))
    8     return wrapper

    加上返回值

    1 import time
    2 def timer(func):
    3     def wrapper(*args,**kwargs):
    4         start_time=time.time()
    5         res=func(*args,**kwargs)
    6         stop_time=time.time()
    7         print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time))
    8         return res
    9     return wrapper

    使用装饰器

    1 def cal(array):
    2     res=0
    3     for i in array:
    4         res+=i
    5     return res
    6 
    7 cal=timer(cal)
    8 cal(range(10))

    语法糖@

    1 @timer  #@timer就等同于cal=timer(cal)
    2 def cal(array):
    3     res=0
    4     for i in array:
    5         res+=i
    6     return res
    7 
    8 cal(range(10))

    八 装饰器应用示例

    # 京东登录(无参数)
    # 利用用户列表,for循环来遍历该字典
    user_list=[
        {'name':'alex','passwd':'123'},
        {'name':'linhaifeng','passwd':'123'},
        {'name':'wupeiqi','passwd':'123'},
        {'name':'yuanhao','passwd':'123'},
    ]
    current_dic={'username':None,'login':False}    #记录下当前用户的状态
    
    #加上认证功能的装饰器函数:参数、返回值
    #登录一次之后,不用每次都再输。应该记录下登录一次的状态(用一个全局变量来实现)
    def auth_func(func):            #函数名
            def wrapper(*args,**kwargs):
              if auth_type == 'filedb':        
                    if current_dic['username'] and current_dic['login']:
                        res = func(*args, **kwargs)
                        return res
                    username=input('用户名:').strip()
                    passwd=input('密码:').strip()
                    for user_dic in user_list:        #遍历列表中所有记录是否与输入的名字密码匹配
                        if username == user_dic['name'] and passwd == user_dic['passwd']:
                            current_dic['username']=username    #记录下登录的状态:拿的就是全局变量的引用
                            current_dic['login']=True
                            res = func(*args, **kwargs)            #验证成功了才可以直接运行函数
                            return res                            #wrapper函数直接结束,不必再加break语句了
                    else:
                        print('用户名或者密码错误')        #此else与for连用,不是循环一次后的if连用。列表中用户名和密码全for循环完毕了return wrapper
        return auth_func
    
    @auth
    def index():                        #已经输入正确用户名及密码了
        print('欢迎来到京东主页')
    
    @authdef home(name):
        print('欢迎回家%s' %name)
    
    @authdef shopping_car(name):
        print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))
    
    print('before-->',current_dic)
    index()
    print('after--->',current_dic)
    home('产品经理')
    shopping_car('产品经理')
    复制代码
    user_list=[
        {'name':'alex','passwd':'123'},
        {'name':'linhaifeng','passwd':'123'},
        {'name':'wupeiqi','passwd':'123'},
        {'name':'yuanhao','passwd':'123'},
    ]
    
    current_user={'username':None,'login':False}
    def auth(auth_type='file'):
        def auth_deco(func):
            def wrapper(*args,**kwargs):
                if auth_type == 'file':
                    if current_user['username'] and current_user['login']:
                        res=func(*args,**kwargs)
                        return res
                    username=input('用户名: ').strip()
                    passwd=input('密码: ').strip()
    
                    for index,user_dic in enumerate(user_list):
                        if username == user_dic['name'] and passwd == user_dic['passwd']:
                            current_user['username']=username
                            current_user['login']=True
                            res=func(*args,**kwargs)
                            return res
                            break
                    else:
                        print('用户名或者密码错误,重新登录')
                elif auth_type == 'ldap':
                    print('巴拉巴拉小魔仙')
                    res=func(*args,**kwargs)
                    return res
            return wrapper
        return auth_deco
    
    
    #auth(auth_type='file')就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type='file')
    #就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type='file'参数
    @auth(auth_type='ldap')
    def index():
        print('欢迎来到主页面')
    
    @auth(auth_type='ldap')
    def home():
        print('这里是你家')
    
    def shopping_car():
        print('查看购物车啊亲')
    
    def order():
        print('查看订单啊亲')
    
    # print(user_list)
    index()
    # print(user_list)
    home()
    复制代码

     装饰器运行流程

    import time
    def timmer(func): #func=test1   第二步
    # wrapper中参数数目不要写死,用列表装
        def wrapper(*args,**kwargs): #第五步  #test('linhaifeng',age=18)  元祖args=('linhaifeng')  kwargs={'age':18}
            start_time=time.time()     #第六步 
            res=func(*args,**kwargs) #第七步,接着去找test函数定义去了   就是在运行test()         func(*('linhaifeng'),**{'age':18})
           #wrapper中怎么接收的就怎么传给func
            stop_time = time.time()     #第十二步
            print('运行时间是%s' %(stop_time-start_time))        #第十三步
            return res            ##第十四步  加入返回值,结束wrapper
        return wrapper            #第三步
    
    @timmer #test=timmer(test)    #第一步:运行这个执行timmer函数,直接返回wrapper地址给test,然后到test()调用
    def test(name,age):            #第八步:对应wrapper中形参表也要加
        time.sleep(3)            #第九步
        print('test函数运行完毕,名字是【%s】 年龄是【%s】' %(name,age))        #第十步
        return '这是test的返回值'    #第十一步
    test()                    #第四步,直接运行wrapper函数
    # 京东登录:auth函数中带参数:数据库的认证类型来源
    # 带参数的少用,不带参数的更加常用
    # 利用用户列表,for循环来遍历该字典
    # 缺点1、认证来源:用户列表应该从数据库里取出来。写死了数据库
    #(可以将user_list写到文件当中便于增删改。注意提取文件内容时都是得到字符串,用eval剥离出来转化为字典)
    user_list=[
        {'name':'alex','passwd':'123'},
        {'name':'linhaifeng','passwd':'123'},
        {'name':'wupeiqi','passwd':'123'},
        {'name':'yuanhao','passwd':'123'},
    ]
    current_dic={'username':None,'login':False}    #记录下当前用户的状态
    
    #加上认证功能的装饰器函数:参数、返回值
    #登录一次之后,不用每次都再输。应该记录下登录一次的状态(用一个全局变量来实现)
    def auth(auth_type='filedb'):
        def auth_func(func):            #函数名
            def wrapper(*args,**kwargs):
                print('认证类型是',auth_type)        
                if auth_type == 'filedb':        
                    if current_dic['username'] and current_dic['login']:
                        res = func(*args, **kwargs)
                        return res
                    username=input('用户名:').strip()
                    passwd=input('密码:').strip()
                    for user_dic in user_list:        #遍历列表中所有记录是否与输入的名字密码匹配
                        if username == user_dic['name'] and passwd == user_dic['passwd']:
                            current_dic['username']=username    #记录下登录的状态:拿的就是全局变量的引用
                            current_dic['login']=True
                            res = func(*args, **kwargs)            #验证成功了才可以直接运行函数
                            return res                            #wrapper函数直接结束,不必再加break语句了
                    else:
                        print('用户名或者密码错误')        #此else与for连用,不是循环一次后的if连用。列表中用户名和密码全for循环完毕了
                elif auth_type == 'ldap':
                    print('鬼才特么会玩')
                    res = func(*args, **kwargs)
                    return res
                else:
                    print('鬼才知道你用的什么认证方式')
                    res = func(*args, **kwargs)
                    return res
    
            return wrapper
        return auth_func
    
        #对auth_func添加参数,加括号相当于直接运行auth函数,因此在这里向无参数形式当中加入return auth_func
    @auth(auth_type='filedb') 
    # auth函数的返回值:auth_func=auth(auth_type='filedb')-->@auth_func 附加了一个auth_type  
    # --->index=auth_func(index)这个指向的返回值还是wrapper,继续执行wrapper
    def index():                        #已经输入正确用户名及密码了
        print('欢迎来到京东主页')
    
    @auth(auth_type='ldap')
    def home(name):                    
        print('欢迎回家%s' %name)
    
    @auth(auth_type='sssssss')
    def shopping_car(name):
        print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))
    
    print('before-->',current_dic)
    index()
    print('after--->',current_dic)
    home('产品经理')
    shopping_car('产品经理')

    九 超时装饰器

    复制代码
    import sys,threading,time
    
    
    class KThread(threading.Thread):
    
        """A subclass of threading.Thread, with a kill()
    
        method.
    
    
    
        Come from:
    
        Kill a thread in Python:
    
        http://mail.python.org/pipermail/python-list/2004-May/260937.html
    
        """
    
        def __init__(self, *args, **kwargs):
    
            threading.Thread.__init__(self, *args, **kwargs)
    
            self.killed = False
    
    
    
        def start(self):
    
            """Start the thread."""
    
            self.__run_backup = self.run
    
            self.run = self.__run      # Force the Thread to install our trace.
    
            threading.Thread.start(self)
    
    
    
        def __run(self):
    
            """Hacked run function, which installs the
    
            trace."""
    
            sys.settrace(self.globaltrace)
    
            self.__run_backup()
    
            self.run = self.__run_backup
    
    
    
        def globaltrace(self, frame, why, arg):
    
            if why == 'call':
    
              return self.localtrace
    
            else:
    
              return None
    
    
    
        def localtrace(self, frame, why, arg):
    
            if self.killed:
    
              if why == 'line':
    
                raise SystemExit()
    
            return self.localtrace
    
    
    
        def kill(self):
    
            self.killed = True
    
    
    
    class Timeout(Exception):
    
        """function run timeout"""
    
    
    
    def timeout(seconds):
    
        """超时装饰器,指定超时时间
    
        若被装饰的方法在指定的时间内未返回,则抛出Timeout异常"""
    
        def timeout_decorator(func):
    
            """真正的装饰器"""
    
    
    
            def _new_func(oldfunc, result, oldfunc_args, oldfunc_kwargs):
    
                result.append(oldfunc(*oldfunc_args, **oldfunc_kwargs))
    
    
    
            def _(*args, **kwargs):
    
                result = []
    
                new_kwargs = { # create new args for _new_func, because we want to get the func return val to result list
    
                    'oldfunc': func,
    
                    'result': result,
    
                    'oldfunc_args': args,
    
                    'oldfunc_kwargs': kwargs
    
                }
    
                thd = KThread(target=_new_func, args=(), kwargs=new_kwargs)
    
                thd.start()
    
                thd.join(seconds)
    
                alive = thd.isAlive()
    
                thd.kill() # kill the child thread
    
                if alive:
    
                    raise Timeout(u'function run too long, timeout %d seconds.' % seconds)
    
                else:
    
                    return result[0]
    
            _.__name__ = func.__name__
    
            _.__doc__ = func.__doc__
    
            return _
    
        return timeout_decorator
    
    
    @timeout(5)
    
    def method_timeout(seconds, text):
    
        print('start', seconds, text)
    
        time.sleep(seconds)
    
        print('finish', seconds, text)
    
        return seconds
    
    
    method_timeout(6,'asdfasdfasdfas')
  • 相关阅读:
    POJ 最小球覆盖 模拟退火
    POJ 1379 模拟退火
    PythonTip(2)
    PythonTip(1)
    LA 3353 最优巴士线路设计
    LA 4254 贪心
    判断分析
    因子分析——因子得分
    因子分析——应用
    因子分析——因子旋转
  • 原文地址:https://www.cnblogs.com/Josie-chen/p/8707322.html
Copyright © 2011-2022 走看看