python,day2,函数

内容大纲

1、函数的基本使用
	先定义
		三种定义方式
	后调用
		三种调用方式
	返回值
		三种返回值的方式
		
2、函数的参数
	形参与实参的介绍
		1、形参
		2、实参
		3、新参与实参的关系
	形参与实参的具体使用
		1、位置参数
		2、关键字参数
		3、默认参数
		4、可变长参数
		5、命名关键字参数(了解)

3、名称空间与作用域、函数对象、闭包函数(进阶)
	命名空间
		1、内置命名空间
		2、全局命名空间
		3、局部命名空间
		4、命名空间加载顺序
		5、命名空间销毁顺序
		6、名称空间查找优先级
	作用域
		1、局部作用域
		2、全局作用域
	函数对象
	闭包函数
		

4、无参装饰器、有参装饰器
		1、什么是装饰器
		2、为什么要用装饰器
		3、如何用
			1、无参装饰器模板
			2、有参装饰器模板
			3、叠加多个装饰器加载运行分析

5、可迭代对象:迭代器、生成器(自定义的迭代器)
		1、什么是迭代器
		2、为什么要有迭代器
		3、迭代器原理
		4、什么是生成器

6、三元表达式、生成式
		1、三元表达式语法
		2、列表生成式
		3、字典生成式
		4、集合生成式
		5、生成式表达式

7、函数的递归调用
		1、具体概念
		2、递归的两个阶段
		3、递归应用

8、二分法(算法)

9、匿名函数
		1sorted排序应用
		2map的应用(了解)
		3filter的应用(了解)
		4reduce的应用(了解)
		
10、内置函数(待补充)

11、面向过程的编程思想(武功秘籍)

1、函数的基本使用

#一函数定义
    #定义语法
    '''
    def 函数名(参数):
    """文档描"""
    函数体
    return值
    '''
    #定义函数发生的事情
        #1、申请内存空间保存函体代码
        #2、将上述内存地址绑定函数名
        #3、定义函数不会执行函数体代码,但会检测函数体语法
        #调用函数发生的事情
        #1、通过函数名找到函数的内存地址
        #2、然后加口号就是在出发函数体代码的执行

    #形式一:无参函数
        def func():
            print('哈哈')

    #形式二:有参函数,调用的时候也需要传参数
        def func(x,y):
            print(x,y)

    #形式三:空函数,函数体代码为pass
        def func(x,y):
            pass

    #三种定义方式的使用案例
        #1、无参函数的应用场景
            def interactive():
                name=input('username=')
                age=input('userage=')
                msg='名字:{},年龄:{}'.format(name,age)
                return msg
        #2、有参函数的应用场景
            def add(x,y):
                #x=20
                #y=30
                res=x+y
                return res
        #3、空函数的应用场景 构思代码的时候
            def func():
                pass


#二、调用函数
    #1、语句的形式:只加括号调用函数
    func()
    func(1,2)

    #2、表达式形式:
        def func(x,y):
            res=x+y
            return res
        #赋值表达式
        #res=func(1,2)
        #print(res)
        #数学表达式
        #res=func(1,2)*10
        #print(res)

    #3、函数调用可以当作参数
        func(func(1,2),10)

    #4、函数的递归调用:是函数嵌套调用的一种特殊形式,本质就是循环
        #具体指:
            #在调用一个函数的过程中又直接或者间接调用到本身
            def f1(): #直接调用本身
                print('是我是我还是我')
                f1()
            f1()

            def f1():#间接调本身
                print('f1')
                f2()
            def f2()
                print('f2')
                f1()
        #强调:递归不应该无限的调用下去,必须在满足某种条件下结束递归
            def func(n)
                if n >10:
                    return
                print(n)
                n+=1
                func(n)
        #递归的两个阶段:
            #回溯:一层一层调用下去
            #递推:满足某种结束条件,结束递归调用,然后一层一层返回
        #递归应用:
            l = [1,2,3,[1,2,3]]
            def f1(l)
                for x in l :
                    if type(x) is list:
                        #如果是列表,应该循环、再判断
                        f1(x)
                    else:
                        print(x)


#三、函数返回值
    #return是函数结束的标志,即函数体单吗一旦运行到return会立刻终止函数运行
    #1、返回None:函数体内没有return,或者return后没有参数
    #2、返回一个值:return参数后更一个值
    #3、返回多个值:用逗号分开多个值,会被return返回成元组

2、函数的参数

#函数参数的使用
    #一、形参与实参的介绍
        #形参:在定义函数阶段的函数称之为形式参数,简称形参,相当于变量名
            def func(x,y):
                print(x,y)
        #实参:在调用函数阶段传入的值称之为实际参数,简称实参,相当于变量值
            func(1,2)
        #实参与形参的关系
            #1、在调用阶段,实参会赋值给形参
            #2、这种绑定关系只能在函数体内使用
            #3、实参与形参的绑定关系在函数调用时生效,函数调用结束后接触绑定关系

    #二、形参与实参的具体使用
        #1、位置参数:按照从左到右的顺序一次定义的参数称之为位置参数
            #1.1、位置形参:在函数定义阶段,按照从左到右的顺序直接定义的变量名
                #特点:必须被传值,多一个不行少一个也不行
                def func(x,y):
                    print(x,y)
                func(1,2,3)
                func(1,)
            #1.2、位置实参:在函数调用阶段,按照从左到由的顺序一次传入的值
                #特点:按照顺序与形参一一对应
                func(1,2)
                func(2,1)
        #2、关键字参数:在函数调用阶段,按照key=value形式传入的值
            #特点:可以指定参数传值
            #位置:1、实参和关键字参数混用,位置实参必须放在关键字实参前
            #    2、不能为同一个形参重复传值
                def func(x,y):
                    print(x,y)
                func(y=1,x=2)

        #3、默认参数:
            #3.1:默认形参:在定义函数阶段,就已经被赋值的形参,称之为默认参数
                #特点:在定义阶段已经被赋值,在调用阶段可以不为其赋值
                def func(x,y,c,l=None)
                    if l is None:
                        l = []
                    l.append(x)
                    l.append(y)
                    l.append(z)
                    print(l)
        #4、可变长度的参数(*与**的用法):在调用函数时,传入的值(实参)的个数不固定,对应着真对溢出的实参必须由对应的形参来接收
            #4.1、*形参名:用来接收溢出的位置实参,溢出的位置实参会被*保存成元组的格式然后赋值紧跟气候的元组名
                #*可以用在实参中,实参中带*,先*后的值打散成位置实参
                def func(*args):
                    res=0
                    for item in args:
                        res+=item
                res = func(1,2,3,4,5)
                print(res)

                func(*[1,2,3])  #func(1,2,3)
                func(*'hello')  #func('h','e','l','l','o')
            #4.2、**新参名:用来接收溢出的关键字实参,**会将溢出的关键字实参保存成字典格式,然后赋值给紧跟其后的形参名
                #**可以用在实参中(**后只能是字典),实参中带**,先**后的值打散成关键字实参
                def func(x,y,**kwargs):
                    print(x,y,kwargs)
                func(1,y=2,a=1,b=2,c=3)
                func(**{'x':1,'y':2})  #func(x=1,y=2)
            #5、命名关键字参数(了解),在定义函数时,*后定义的参数,如下所示,称之为命名关键字参数
                def func(x,y,*,a,b)  #a,b为命名关键字函数
                    print(x,y)
                    print(a,b)

3、名称空间与作用域、函数对象、闭包函数(进阶)

#名称空间与作用域、函数对象、闭包函数(进阶)
    #1、名称空间(namespaces):存放名字的地方,是对栈区的划分
        #1、内置名称空间
            #存放的名字:存放的python解释器内置的名称
            #存放的周期:python解释器启动则产生,python解释器关闭则销毁
        #2、全局名称空间
            #存放的名字:运行顶级代码所产生的名字,不是函数内定义,也不是内置,剩下的都是全局名称空间
            #存放的周期:python文件执行则产生,python文件运行完毕后销毁
        #3、局部名称空间
            #存放的名字:在调用函数时,运行函体代码过程中产生的函数体内的名字
            #存放的周期:在调用函数时存货,函数调用完毕后则销毁
        #4、命名空间加载顺序:内置>全局>局部
        #5、命名空间销毁顺序:局部>全局>内置
        #6、名字的查找优先级:当前所在位置向上一层一层查找
            #关键点1、命名空间的‘嵌套’关系是以函数定义阶段为准,与调用位置无关

    #2、作用域:作用范围
        #全局作用域:内置名称空间、全局名称空间
            #1、全局存活
            #2、全局有效:被所有函数共享
        #局部作用域:局部名称空间的名字
            #1、临时存货
            #2、局部有效:函数内有效
    #4、函数对象
        #1、可以赋值
                def func():
                    print('from func')
                f = func
                print(f,func)
        #2、可以当作函数的参数传入
                def foo(x)
                    print(x)
                foo(func)
        #3、可以吧函数当作另一个函数的返回值
                def foo(x)
                    return x
                res = foo(func)
                print(res)
        #4、可以当作容器类型的一个元素
                l=[func,]
                l[0]
                dic={'k1':func}
        #5、函数的嵌套调用:在调用一个函数的过程中又调用其他函数
                def max2(x,y):
                    if x>y:
                        return x
                    else:
                        return y
                def max4(a,b,c,d):
                    #第一步:比较a,b得到res1
                    res1 = max2(a,b)
                    #第二步:比较res1和c得到res2
                    res2 = max2(res1,c)
                    #第三步:比较res2和d得到res3
                    res3 = max(res2,d)
                    return res3
                res = max4(1,2,3,4)
                print(res)
            #6、函数的嵌套定义:在函数内定义其他函数
                def f1():
                    def f2():
                        pass

    #5、闭包函数
        #1、大前提:闭包函数=命名空间与作用域+函数嵌套+函数对象
            #核心点:名字的查找关系是以定义阶段为准
        #2、什么是闭包函数
            #’闭‘函数指的是该函数是内嵌函数
            #’包‘函数指的是该函数包含对外层函数作用域名字的应用(不是对全局作用域)
        #3、为什么要用到闭包函数
            #两种为函数体传参的方式
            #方式一:直接把函数体需要的擦书定义成形参
                def f2(x):
                    print(x)
                f2(1)
            #方式二:利用名称空间和作用域将值包给f2
            def f1(x):
                def f2(x):
                    print(x)
                return f2
            x = f1(1)
            print(x)

4、无参装饰器、有参装饰器

#装饰器
    #一、什么是装饰器
        #器:指的是工具,可以定义成函数
        #装饰:指的是为其他事物添加额外的东西点缀
        #装饰器:装饰器指的是定义一个函数,该函数是用来装饰其他函数的,为其他函数添加额外的功能
    #二、为什么要用装饰器
        #开放封闭原则
            #开放:指的是对拓展功能是开放的
            #封闭:指的是对修改源代码是封闭的
        #装饰器就是在不修改被装饰器对象源代码以及调用方式的前提下为被装饰对象添加新功能

    #三、如何用
        #无参装饰器模板
			def outter(func):   #func是被装饰对象的内存地址
			    @wraps()  #相当于获取原函数的所有功能,然后赋值给wrapper
			    def wrapper(*args,**kwargs):    #wrapper的参数取决于被装饰对象
			        #调用原函数
			        #添加新功能
			        res = func(*args,**kwargs)  #为被装饰对象传参数,并赋值给res,然后返回
		        return res
		    return wrapper
        #有参装饰器模板
            def 有参装饰器(x,y,z):
                x=111
                def outter(func):
                    def wrapper(*args,**kwargs):
                        #调用原函数
                        #添加新功能
                        res = func(*args,**kwargs)
                        return res
                    return wrapper()
                return outter
            @有参装饰器(x,y,z)
            def 被装饰对象():
                pass
        #叠加多个装饰器的加载、运行分析
            #@deco1 #index=deco1(deco2.wrapper的内存地址)
            #@deco2 #deco2.wrapper的内存地址=deco2(deco3.wrapper的内存地址)
            #@deco3 #deco3.wrapper的内存地址=deco3(index)
            #def index():
            #   pass



	#四、案例:登录认证装饰器
	def auth(func):
	    def wrapper(*args,**kwargs):
	        usename = input('请输入账号:').strip()
	        pwd = input('请输入密码:').strip()
	        if usename == 'root' and pwd == '123':
	            print('登录成功!')
	            res = func(*args, **kwargs)
	            return res
	        else:
	            print('登录失败')
	    return wrapper

	@auth   #asd = auth()
	def asd():
	    print('登录认证装饰器')
	asd()
	
	@print   #@后面加函数名的意义就是变成这样home = print(home),然后拿到返回值放到@后面
	def home():
	    pass
	
	#五:有参装饰器案例
	def auth(db_type='file'):
    #这个时候需要做数据库辨别,还需要传一个db_type参数
    #由于语法糖@限制,outter只能有一个参数来接收被装饰对象的内存地址
    def outter(func):   #func是被装饰对象的内存地址
        def wrapper(*args,**kwargs):    #wrapper的参数取决于被装饰对象
            name = input('your name:').strip()
            pwd = input('your password:').strip()
            if db_type == 'file':
                print('基于文件的验证')
                if name == 'root' and pwd == '123':
                    res = func(*args, **kwargs)  # 为被装饰对象传参数,并赋值给res,然后返回
                    return res
                else:
                    print('账号密码错误')
            elif db_type =='mysql':
                print('基于mysql的验证')
        return wrapper
    return outter
	# outter = auth(db_type='file')   #将autter放回到全局,然后就可以语法糖调用
	@auth(db_type='mysql')
	#1、先执行auth(db_type='mysql'),然后执行函数体return outter得到outter,将其放在@后面,得到func = outter(func)
	#2、得到func = outter(func)后,再进一步解析,outter(fun)执行函数体得到wrapper,从而得到func = wrapper
	#3、func(1,2) 相当于 func = wrapper,相当于调用wrapper
	#4、将1,2传入wrapper中执行wrapper体代码,然后从中得到返回值
	def func(x,y):
	    print('%d,%d'%(x,y))
	func(1,2)
	
	
	#总结:
	    #装饰器用的是wrapper的功能
	    #但是wrapper里需要各种参数(db_type,func)
	    #所以需要和闭包函数结合使用
	

5、可迭代对象:迭代器、生成器(自定义的迭代器)


#迭代器
    #1、什么是迭代器
        #迭代器指的是迭代取值的工具,迭代是一个重复的过程,每次重复都是基于上一次结果而继续的,单纯的重复并不是迭代


    #2、为什么要有迭代器
        #迭代器是用来迭代取值的工具,而涉及到把多个值循环取出来的类型有:列表、字符串、元组、字典、集合、打开文件
                l=[1,2,3]
                # i=0
                # while i < len(l):
                #     print(l[i])
                #     i+=1
        #上述迭代取值的方式只适用于有缩影的数据类型:列表、字符串、元组
        #为了解决基于索引迭代器取值的局限性,python必须提供一种能够不依赖于索引的取值方式,这就是迭代器


    #3、迭代器原理
        #1、可迭代对象(可以转换成迭代器的对象):内置有__iter__方法的对象
                #可迭代对象.__iter__():得到迭代器对象
        #2、迭代器对象:内置有__next__方法并且内置有__iter__方法的对象
                #迭代器对象.__next__():得到迭代器的下一个值
                #迭代器对象.__iter__():得到迭代器本身,说白了调了和没调一样
        #3、for循环工作原理
                #1、d.__iter__()得到一个迭代器对象
                #2、迭代器对象.__next__()拿到一个返回值,然后将该返回值赋值给k
                #3、循环王府步骤2,知道跳出StopIterator异常for循环会捕捉异常然后结束循环
                d=[1,2,3,4,5]
                for i in d:
                    print(k)
                # d_iter=d.__iter__()
                # while True
                #     try:
                #         print(d_iter.__next__())
                #     except StopIteration:
                #         break
        #4、迭代器优缺点:
            #优点
                #1、不依赖索引的取值方案
                #2、惰性取值;每次只取一个数据,不占内存;迭代器保存的是产生数据的算法,而不是实际的数据。
            #缺点
                #1、除非取尽,否则无法获取迭代器的长度
                #2、只能往后依次取值,不能返回头往前取值,一次性的

#生产器:生成器就是自定义的迭代器
    #1、如何得到自定义的迭代器
        #在函数中定义yield关键字,调用函数并不会执行函数体代码,会放回一个生成器对象
        #有了yield关键字,就有了自定义迭代器的实现方式。yield可以用于返回值,但不同于return,函数一旦遇到return就结束了,而yield可以保存函数的运行状态,用来返回多次值

    #2、应用案例
        #自定义迭代器,自己生产数值
        def my_range(start,stop,step=1):
            print('start...')
            while start<stop:
                start+=step
                yield start
            print('end...')
        g = my_range(1,5,3) #1 3
        res=next(1,5,3)
        print(next(g))

        #生成器的高级玩法之yield挂起函数:yield的表达形式 (了解)
            #x=yield 返回值
            def dog(name):
                print('dog%s准备吃东西啦。。。'%name)
                while True:
                    #x拿到的是yield接收到的值
                    x = yield
                    print('dog%s吃了 %s'%(name,x))]
            g=dog('狗子')
            g.send(None) #等同于next(g)
            g.send('肉包子')
            g.close()   #关闭send

6、三元表达式、生成式

#三元表达式
    #语法格式:条件成立时要返回的值 if 条件else条件不成立要返回的值
    x=1
    y=2
    res = x if x>y else y

#生成式
    #列表生成式
        l = ['hw_dsb','d','k_dsb','b']
        # new_l = []
        # for name in l:
        #     if name.endswith('sdb'):
        #         new_l.append(name)
        new_l = [name for name in l if name.endswith('dsb')]
        #练习:吧所有小写名字全变成大写,吧dsb后缀去掉
        new_l=[name.upper() for name in l]
        new_l=[name.replace('_dsb','') for name in l]
    #字典生成式
        keys = ['name','age']
        dic = {key:None for key in keys}

        items = [('name','egon'),('age',18),('gender','male')]
        res = {k:v for k,v in items if k !='gender'}
    #集合生成式
        keys = ['name','age']
        set1 = {key for key in keys}
        print(set1,type(set1))

    #生成器表达式
        g=sum(cc
    表达式 for i in 可迭代对象 if 条件)
        #此刻g内部一个值也没有,next一下就执行一下

        g=[表达式 for i in 可迭代对象 if 条件]

7、函数的递归调用

#函数的递归调用:是函数嵌套调用的一种特殊形式,本质就是循环
        #具体指:
            #在调用一个函数的过程中又直接或者间接调用到本身
            def f1(): #直接调用本身
                print('是我是我还是我')
                f1()
            f1()

            def f1():#间接调本身
                print('f1')
                f2()
            def f2()
                print('f2')
                f1()
        #强调:递归不应该无限的调用下去,必须在满足某种条件下结束递归
            def func(n)
                if n >10:
                    return
                print(n)
                n+=1
                func(n)
        #递归的两个阶段:
            #回溯:一层一层调用下去
            #递推:满足某种结束条件,结束递归调用,然后一层一层返回
        #递归应用:
            l = [1,2,3,[1,2,3]]
            def f1(l)
                for x in l :
                    if type(x) is list:
                        #如果是列表,应该循环、再判断
                        f1(x)
                    else:
                        print(x)

8、二分法(算法)

#二分法(算法)
        #需求:有一个按照从小到达顺序排列的数字列表
            #需要从该数字列表中找到我们想要的一个数字如何做更搞笑??
            name = [1,2,3,5,6,8,10,11,12,15,46]  #如果列表顺序乱的则 name.sort()排下序
            find_num = 10
            def binary_search(find_num,l):
                print(l)
                if len(l) == 0:
                    print('找的值不存在')
                    return
                mid_index = len(l) //2
                mid_val = l[mid_index]
                if find_num > mid_val:
                    l = l[mid_index+1:]
                    binary_search(find_num,l)
                elif find_num < mid_val:
                    l = l[:mid_index]
                    binary_search(find_num,l)
                else:
                    print('find it')

9、匿名函数

#匿名函数
    #1、有名函数
        #func = 函数的内存地址
        def func(x,y):
            return x+y
    #2、匿名函数
        #lamdab用于定义匿名函数
        print(lambda x,y:x+y )
        #调用匿名函数
            #方式一:
            res = (lambda x,y:x+y)(1,2)
            print(res)
            #方式二:无意义
            func = lambda x,y:x+y
            res = func(1,2)
            print(res)
        #场景:匿名函数由于没有名字,调用一次内存地址就会销毁,所以匿名用于临时调用一次的场景:更多的是将匿名与其他函数配合使用
            #需求1:找出薪资最高的那个人 =》 lili
            #sorted排序应用
                salaries = {
                    'khw':7000,
                    'bxy':13000,
                    'asd':2500
                }
                # def func(k):
                #     return salaries[k]
                # res = max(salaries, key=func)
                res = max(salaries,key=lambda k:salaries[k])    #取最大的
                # res = min(salaries,key=lambda k:salaries[k])    #求最小的
                # res = sorted(salaries,key=lambda k:salaries[k])    #排序
                print(res)

            #1、map的应用(了解)
                l = ['kxx','rxx','zxx']
                # new_l=[name+'_dsb' for name in l]
                # print(new_l)
                res = map(lambda name:name+'_dsb',l)
                print(res) #生成器
            #2、filter的应用(了解)
                l = ['kxx_sb','rxx','zxx']
                # res = (for name in l if name.endswith('_sb'))
                # print(res)
                res = filter(lambda name:name.endswith('sb'),l)
                print(res)
            #3、reduce的应用(了解)
                from functools import reduce
                reduce(lambda x,y:x+y,[1,2,3],10) #11 13 16
                print(res)
  
总结:
lambda x,y:x+y         #冒号后面直接写函数体,不需要写return,默认将函数体return
max(salaries,key=func)    #将salaries迭代出的内容交给func执行,然后func执行返回值给max进行比较取值
max(salaries,key=lambda k:salaries) #k代表参数,冒号后面代表函数体,将参数传给函数体
 

10、内置函数(待补充)

11、面向过程的编程思想(武功秘籍)

#编程思想/范式
    #面向过程的编程思想:
        #核心是“过程”二字、过程及流程,指的是做事的步骤:先什么,再什么,后什么
        #基于该思想编写程序,就好比再设计一条流水线
        #优点:复杂的问题流程化、进而简单化
        #缺点:扩展性非常差

        #面向对象的编程思想应用场景解析:
        #1、不是所有的软件都要频繁更迭:比如编写脚本
        #2、即便是一个软件需要频繁更迭,也并不代表这个软件所有的组成部分都需要一起更迭

    #函数式编程:将计算机的运算视为数学意义上的运算
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值