zoukankan      html  css  js  c++  java
  • python 函数

    函数对象

    在面向对象编程中 一切皆对象

    具体的体现
    1.函数可以被引用
    2.函数可以作为函数的参数
    3.函数可以作为函数的返回值
    4.可以被存储到容器类型中

    def pay():
        print('支付')
    def save():
        print('存钱')
    def cheak():
        print('查看')
    
    
    
    
    dic={'1':pay,'2':save,'3':cheak}
    while True:
         l=['支付','存钱','查看']
         for i,k in enumerate(l):
             print(i+1,k)
         cmd=input('>>>:')
         if cmd in dic:
             dic[cmd]()
         else:
             print('指令错误')

    2.函数嵌套
    1.嵌套调用 在一个函数中调用了另一个函数
    2.嵌套定义 在一个函数中定义了另一个函数
    定义在函数内的函数 只能函数内使用 外界不能访问

    def func1():
        print("func1")
    
    
    def func2():
        print("func2")
    
         func1()
    
     func2()
    嵌套调用
    def func1():
         print("func1")
    
         def func2():
             print("func2")
    
         func2()
    
    func1()
    嵌套定义

    3.函数的名称空间

    存储名称的空间
    名称空间的分类
    内置名称空间 存储解释器自带的一些名称与值的对应关系
    (python解释器启动时创建 所有代码全部执行完毕 关闭解释器时 销毁)
    print len max min

    全局名称空间 哪些数据会存储在全局空间?
    文件级别的名称 只要你的名字的定义是顶着最左边写的就在全局空间
    除了内置的函数内的 都在全局中
    (执行py文件创建全局名称空间 关闭解释器时 销毁)


    局部名称空间 只要是函数内的名称就是局部的
    (调用函数时创建 函数执行完毕就销毁)

    名称空间的加载顺序
    内置的 -> 全局的 ->局部的

    名称的查找顺序
    局部 -> 全局的 -> 内置的

    4.函数的作用域

    作用域(作用范围)
    域 指的是区域 范围的的意思
    全局的名称空间和内置的名称空间 在使用上没什么区别
    局部的和全局的内置的 就区别了 局部定义的只能在局部使用
    给三个空间划分范围

    全局的和内置可以划分为同一个范围
    global 表示的全局范围 就是所谓的全局作用域

    局部的单独划分为一个范围
    local 局部作用域

    globals()
    locals()

    print(locals())#查看全局作用域,当locals在全局作用域时,功能和globes相同
    print(globals())
    def func():
         a = 100
         print(locals())#查看局部作用域
    
    func()
    age = 18
    def func2():
         # 明确声明  要使用全局中的age
       global age
        age = 19
    
        print(age)
    
    func2()
    print(age)
    a = 1
    def func3():
        a = 10
        def inner():
            # 明确声明 要使用上一中的 a 如果上一层没有  则找上上层  但是注意 不能找到全局中的
            nonlocal a
            a = 100
            print(a)
        inner()
        print("这是func3中a",a)
    
    func3()
    print(a)

    5.闭包函数

    age = 20
    # 如下就是一个闭包函数
    def fun1():
        age = 18
        def inner():
            print("hello")
            print(age)
        # 在返回这个内部的函数时 不是单纯的返回函数  还把函数中访问到的局部名称一起打包了
        # 相当于将内部函数与 访问的数据打包在一起了  闭包这个名字就是这么得来的
        return inner
    f = fun1() # f 就是inner
    f()
    
    # 函数的作用域在定义时就固定了  与调用没有关系
    # 闭包函数的模板
    def func2():
        a = 1
        b = 10
        def inner():
            print(a)
            print(b)
        return inner
    什么是闭包函数
    1.定义在另一个函数内的函数
    2.内部的的函数访问了外部的名称数据 注意 不包含全局的)

    6.装饰器

    什么是装饰器
    什么是装饰 给一个已有的对象(一个函数) 添加新的功能
    为什么要装饰 增强功能
    器 指一个工具 在python中 值得是具备某个功能的函数

    简单的说:装饰器就是 一个用于给其他函数增加功能的函数
    import time
    
    def download():
        print('开始下载xxx.mp4')
        time.sleep(2)
        print('xxxx.mp4 下载完成')
        
        
    # 请你统计下载耗时
    start_time = time.time()
    download()
    end_time = time.time()
    print('下载耗时',(end_time-start_time))
    
    def download2():
        start_time = time.time()
        print("开始下载xxx.mp4")
        time.sleep(2)
        print("xxxx.mp4 下载完成!")
        end_time = time.time()
        print("下载耗时", (end_time - start_time))
    
    download2()
    def max2(x,y):
        if x > y:
            return x
        else:
            return y
    
    res=max2(10,20)
    
    x=10
    y=20
    
    # res=x if x > y else y
    # print(res)
    
    
    res='OK' if False else 'No'
    print(res)
    三元表达式
    
    
    
    
    
    def outter(func):
        def inner():
            strat_time = time.time()
            func()
            end_time = time.time()
            print('下载耗时',(end_time-start_time))
        return inner
    download=outter(download)
    download()
    # 叠加多个装饰器
    # 1. 加载顺序(outter函数的调用顺序):自下而上
    # 2. 执行顺序(wrapper函数的执行顺序):自上而下
    
    
    def outter1(func1): #func1=wrapper2的内存地址
        print('加载了outter1')
        def wrapper1(*args,**kwargs):
            print('执行了wrapper1')
            res1=func1(*args,**kwargs)
            return res1
        return wrapper1
    
    def outter2(func2): #func2=wrapper3的内存地址
        print('加载了outter2')
        def wrapper2(*args,**kwargs):
            print('执行了wrapper2')
            res2=func2(*args,**kwargs)
            return res2
        return wrapper2
    
    def outter3(func3): # func3=最原始的那个index的内存地址
        print('加载了outter3')
        def wrapper3(*args,**kwargs):
            print('执行了wrapper3')
            res3=func3(*args,**kwargs)
            return res3
        return wrapper3
    
    
    
    @outter1 # outter1(wrapper2的内存地址)======>index=wrapper1的内存地址
    @outter2 # outter2(wrapper3的内存地址)======>wrapper2的内存地址
    @outter3 # outter3(最原始的那个index的内存地址)===>wrapper3的内存地址
    def index():
        print('from index')
    
    print('======================================================')
    index()
    
    '''
    叠加多个装饰器
     
    有参装饰器
    import time
    
    current_user={'user':None}
    
    def auth(engine='file'):
        def outter(func):
            def wrapper(*args,**kwargs):
                if current_user['user']:
                    res=func(*args,**kwargs)
                    return res
    
                user=input('username>>>: ').strip()
                pwd=input('password>>>: ').strip()
    
                if engine == 'file':
                    # 基于文件的认证
                    if user == 'egon' and pwd == '123':
                        print('login successfull')
                        current_user['user']=user
                        res=func(*args,**kwargs)
                        return res
                    else:
                        print('user or password error')
                elif engine == 'mysql':
                    # 基于mysql的认证
                    print('基于mysql的认证')
                elif engine == 'ldap':
                    # 基于ldap的认证
                    print('基于ldap的认证')
                else:
                    print('不知道engine')
            return wrapper
        return outter
    
    @auth('ldap') #@outter #index=outter(index) # index=wrapper
    def index():
        time.sleep(1)
        print('from index')
    
    @auth('mysql') #@outter # home=outter(home) #home=wrapper
    def home(name):
        print('welcome %s' %name)
    
    index()
    home('egon')
    View Code
    def max2(x,y):
        if x > y:
            return x
        else:
            return y
    
    res=max2(10,20)
    
    x=10
    y=20
    
    # res=x if x > y else y
    # print(res)
    
    
    res='OK' if False else 'No'
    print(res)
    三元表达式
     
    # 列表生成式
    # l=[]
    # for i in range(10):
    #     if i > 4:
    #         l.append(i**2)
    #
    #
    #
    # l=[i**2 for i in range(10) if i > 4]
    # print(l)
    
    
    # names=['egon','alex_sb','kevin_sb','hxx_sb','cxx_sb']
    # sbs=[]
    # for name in names:
    #     if name.endswith('sb'):
    #         sbs.append(name)
    
    # sbs=[name.upper() for name in names if name.endswith('sb')]
    
    
    
    # print([name.upper() for name in names])
    # print([name for name in names if name.endswith('sb')])
    
    
    # 字典生成式
    # res={i:i**2 for i in range(10) if i > 3}
    # print(res)
    生成式
    # func()
    # func()
    # func()
    # 匿名函数就是只定义了一个函数的内存地址,主要用于临时使用一次的场景
    # func=lambda x,y:x+y
    # print(func)
    # print(func(1,2))
    
    # res=(lambda x,y:x+y)(1,2)
    # print(res)
    
    
    # print(max([10,11,-3,23]))
    # salaries={
    #     'egon':3000,
    #     'alex':100000000,
    #     'wupeiqi':10000,
    #     'yuanhao':2000
    # }
    # def func(k):
    #     return salaries[k]
    
    # print(max(salaries,key=lambda k:salaries[k]))
    # print(min(salaries,key=func))
    # for循环的结果         比较依据
    # 'egon'                3000
    # 'alex'                100000000
    # 'wupeiqi'             10000
    # 'yuanhao'             2000
    
    # l=[4,2,3]
    # l_new=sorted(l,reverse=True)
    # print(l_new)
    #
    #
    # print(sorted(salaries,key=lambda k:salaries[k],reverse=True))
    #
    匿名函数

    迭代器

    1. 什么是迭代器
    什么是迭代?
    迭代是一个重复的过程,但是每次重复都是基于上一次重复的结果而继续
    #下列循环知识单纯的重复
    while True:
    print(1)

    # 基于索引的迭代取值
    l=['a','b','c']
    i=0

    while i < len(l):
    print(l[i])
    i+=1
    什么是迭代器?
    迭代取值的工具
    2. 为什么要用迭代器
    迭代器
    优点
    1. 提供一种不依赖索引的迭代取值方式
    2. 更节省内存
    缺点:
    1. 不如按照索引的取值方式灵活
    2. 取值一次性的,只能往后取,无法预测值的个数

    3. 如何用迭代器
    可迭代的对象:strlist upledictset文件对象
    但凡内置有__iter__方法的对象都称之为可迭代对象

    迭代器对象: 文件对象
    既内置有__iter__方法又内置有__next__方法的对象都称之为迭代器对象


    调用可迭代对象下__iter__方法,会有一个返回值,该返回值就是内置的迭代器对象
     
    # s='abcdef'
    # l=['a','b','c']
    # d={'k1':111,'k2':222,'k3':333}
    
    # iter_d=d.__iter__()
    # # print(iter_d)
    #
    # try:
    #     print(iter_d.__next__())
    #     print(iter_d.__next__())
    #     print(iter_d.__next__())
    #     print(iter_d.__next__())
    # except StopIteration:
    #     print('取值完毕')
    
    
    d={'k1':111,'k2':222,'k3':333}
    # d={1,2,3,4,5}
    # d=[1,2,3,4]
    
    # iter_d=d.__iter__()
    # iter_d=iter(d) #d.__iter__
    
    # print(next(iter_d)) #iter_d.__next__()
    
    # print(len(d))
    print(d.__len__())
    
    
    # print(iter_d.__iter__().__iter__().__iter__() is iter_d)
    
    # print(d.__iter__().__next__())
    # print(d.__iter__().__next__())
    # print(d.__iter__().__next__())
    
    
    
    # while True:
    #     try:
    #         v=iter_d.__next__()
    #         print(v)
    #     except StopIteration:
    #         break
    #
    # print('第二次取值')
    #
    # iter_d=d.__iter__()
    # while True:
    #     try:
    #         v=iter_d.__next__()
    #         print(v)
    #     except StopIteration:
    #         break
    #
    
    # for k in d:
    #     print(k)
    
    #for循环的底层原理:
    # 1. 调用in后面那个值/对象的__iter__方法,拿到一个迭代器对象iter_obj
    # 2. 调用迭代器对象iter_obj.__next__()将得到的返回值赋值变量名k,循环往复直到取值完毕抛出异常StopIteration
    # 3. 捕捉异常结束循环
    View Code
    生成器就是一种自定义的迭代器

    如何得到生成器?
    但凡函数内出现yield关键字,再去调用函数不会立即执行函数体代码,会得到一个返回值,该返回值就是生成器对象,
    即自定义的迭代器

    # def func():   
    #     print('first')
    #     yield 1
    #     print('second')
    #     yield 2
    #     print('third')
    #     yield 3
    #
    #
    # g=func()
    # # print(g)
    #
    # res1=next(g)
    # print(res1)
    #
    # res2=next(g)
    # print(res2)
    #
    # res3=next(g)
    # print(res3)
    #
    # next(g)
    
    # 总结yield:
    # 1. 提供一种自定义迭代器的解决方案
    # 2. yield & return
    #    相同点: 都可以返回值,返回值没有类型限制个数限制
    #    不同点: return只能返回一次值,yield却可以让函数暂停在某一个位置,可以返回多次值
    
    
    
    # def my_range(start,stop,step=1):
    #     while start < stop: # 5 < 5
    #         yield start # 3
    #         start+=step #start=5
    
    # range(1,5,2) # 1 3
    # for i in my_range(1,5000000000000000000000000000000000000000000,2): # 1 3
    #     print(i)
    View Code
    函数的递归调用与二分法
    1. 函数的递归调用:
    在调用一个函数的过程又直接或者间接地调用该函数本身,称之为递归调用

    递归必须满足两个条件:
    1. 每进入下一次递归调用,问题的规模都应该有所减少
    2. 递归必须有一个明确的结束条件
    递归有两个明确的阶段:
    1. 回溯
    2. 递推

    # age(5)=age(4)+2
    # age(4)=age(3)+2
    # age(3)=age(2)+2
    # age(2)=age(1)+2
    # age(1)=18
    
    # age(n)=age(n-1)+2  # n > 1
    # age(1)=18          # n = 1
    
    # def age(n):
    #     if n == 1:
    #         return 18
    #     return age(n-1)+2
    #
    # print(age(5))
    
    
    # l=[1,[2,[3,[4,[5,[6,[7,[8,[9,]]]]]]]]]
    #
    # def func(list1):
    #     for item in list1:
    #         if type(item) is not list:
    #             print(item)
    #         else:
    #             # 如果是列表,应该...
    #             func(item)
    #
    # func(l)
    
    
    # nums=[3,5,7,11,13,23,24,76,103,111,201,202,250,303,341]
    #
    # find_num=203
    # for num in nums:
    #     if num == find_num:
    #         print('find it')
    #         break
    # else:
    #     print('not exists')
    
    
    nums=[3,5,7,11,13,23,24,76,103,111,201,202,250,303,341]
    
    
    def binary_search(list1,find_num):
        print(list1)
        if len(list1) == 0:
            print('not exist')
            return
        mid_index=len(list1) // 2
        if find_num > list1[mid_index]:
            # in the right
            binary_search(list1[mid_index + 1:],find_num)
        elif find_num < list1[mid_index]:
            # in the left
            binary_search(list1[:mid_index],find_num)
        else:
            print('find it')
    
    binary_search(nums,203)
    View Code

     res=[i for i in range(10)  if i > 5]

    print(res)#这是列表生成式

    g=(i for in range(10) if i >5)

    print(g)

    print(next(g))

    print(next(g))

    print(next(g))

    print(next(g))#这是生成器表达式

    with open('a.txt','rt,encoding='utf8')as f:
    #print(len(f.read())) 统计文件中字符个数
    res = sum(len(line) for line in f)
    print(res) #用生成器表达式的方法统计文件字符个数


     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    电话传递数据加密
    求一个3*3矩阵对角线元素之和
    ASP编程入门进阶(四):内置对象Request 详细出处参考:http://www.jb51.net/article/5887.htm
    ASP编程入门进阶(三):接触脚本程序 详细出处参考:http://www.jb51.net/article/5886.htm
    *****User controls in Winform can not be localized
    Regex字符串處理函數--Split--Replace
    office2007如何自动生成目录
    *****解決gridControl lookupedit click時為空的問題
    测试人员应具备的技能和素养
    eXpressApp Framework簡介
  • 原文地址:https://www.cnblogs.com/BestSkye/p/10034085.html
Copyright © 2011-2022 走看看