zoukankan      html  css  js  c++  java
  • day3函数进阶

    第1章 Day3函数

    1.1 函数与过程的区别

    为什么要有返回值

    是因为下面的程序有可能要以这个函数的返回结果做不同的操作

    #函数
    def func1():
        '''testing1'''
       
    print('in the func1')
        return 0
    #过程
    def func2():
        '''testing2'''
       
    print('in the func2')

    x=func1()
    y=func2()
    print('from func1 is %s' %x)
    print('from func1 is %s' %y)
    过程没定义返回值默认返回None

    1.2 函数的作用

    为了把相同逻辑的代码模块化 可以是程序变得简洁

    提高代码利用率 避免相同代码多次出现

    提高程序的可扩展性

    import time
    def logger():
        time_format = '%Y-%m-%d %X'
       
    time_current = time.strftime(time_format)
        with open('a.txt','a+')as f:
            f.write('%s end action ' %time_current)
    def test1():
        print('in the test1')
        logger()
    def test2():
        print('in the test2')
        logger()
    def test3():
        print('in the test3')
        logger()
    test1()
    test2()
    test3()

    1.3 返回值可以传多个参数

    Python会把他当成一个元组返回

    import time
    def logger():
        time_format = '%Y-%m-%d %X'
       
    time_current = time.strftime(time_format)
        with open('a.txt','a+')as f:
            f.write('%s end action ' %time_current)
    def test1():
        print('in the test1')
        logger()
    def test2():
        print('in the test2')
        logger()
    def test3():
        print('in the test3')
        logger()
    test1()
    test2()
    test3()
     
    def test1():
        pass
    def
    test2():
        return 0
    def test3():
        return 0,'hello',['a','b','c'],{'name':'lieying'}
    x=test1()
    y=test2()
    z=test3()
    print(x)
    print(y)
    print(z)
    执行结果
     

    None

    0

    (0, 'hello', ['a', 'b', 'c'], {'name': 'lieying'})

    1.4 返回值可以是函数名

    def test1():
        print('in the test1')
        pass
    def
    test2():
        print('in the test2')
        return 0
    def test3():
        print('in the test3')
        #return 0,'hello',['a','b','c'],{'name':'lieying'}
       
    return test2    #这里返回的将是test2函数的id
    x=test1()
    y=test2()
    z=test3()
    print(x)
    print(y)
    print(z)

    返回结果

    in the test1

    in the test2

    in the test3

    None

    0

    <function test2 at 0x00000000031220D0>

    1.5 形参

    1.5.1 位置形参:按照从左到右顺序依次定义的参数 必须被传参多一个不行,少一个也不行

    默认参数 也称关键字形参例如
    def foo(x,y,z=1):
        print(x,y,z)
    foo(2,y=3,z=4)
    x 为位置形参 y=1为默认参数
    2 为位置实参

    1.5.2 默认参数

    def test(x,y=2):
        print(x)
        print(y)
    test(1)
    test(1,3)
    def conn(host,port=3306)
        pass
    #默认参数特点:调用函数的时候,默认参数非必须传递
    #用途: 1.默认安装
     

    默认参数必须在位置参数的后面

    def haha(x=1,y):
        print(x,y)
    haha(2)
      File "C:/Users/Administrator/PycharmProjects/python18期/day3/函数.py", line 1
        def haha(x=1,y):
                ^
    SyntaxError: non-default argument follows default argument

    默认参数只在定义阶段赋值一次

    x=100
    def foo(a,b=x):
        print(a,b)
    x=200000000000
    foo('egon')

    默认参数的值应该定义成不可变类型

    1.5.3 命名关键字参数: 在*后面定义的形参成为命名关键字参数,必须是被以关键字实参的形式传值

    def foo(name,age,*,sex,hobby):
        print(name,age,sex,hobby)
    # foo('alex',73,'male','girl')
    foo('alex',73,hobby='boy',sex='female')
    foo(name='alex',sex='male',hobby='girl',age=74)

    1.6 实参

    1.6.1 位置实参:与形参按照位置一一对应

    def test(x,y,z):
        print(x)
        print(y)
        print(z)
    #位置调用

    #1,2,3 为实参
    #test(1,2,3)

    1.6.2 关键字实参:按照key:value的形式指名道姓的给name传参的形式

    def foo(name,age,sex,hobby):
        print(name,age,sex,hobby)
    foo('alex',73,'male','girl')
    foo(name='alex',sex='male',hobby='girl',age=74)

    1.6.3 传参注意事项

    位置实参必须在关键字实参的前面  
     
    def foo(x,y,z=1):
        print(x,y,z)
    foo(2,y=3,4)#这样调用会报错
    不要对同一个形参传多次值
     

    1.7 各种传参的结果

    #*args:接受N个位置参数,转换成元组形式
    # def test(*args):
    #     print(args)
    # test(1,2,3,4,5,5)
    # test(*[1,2,3,4,5,5])# args = tuple
    # def test1(x,*args):
    #     print(x)
    #     print(args)
    # test1(1,2,3,4,5,6,7)
    #**kwargs: 接受N个关键字参数,转换成字典的方式
    # def test2(**kwargs):
    #     print(kwargs)
    #     print(kwargs['name'])
    #     print(kwargs['age'])
    #     # print(kwargs['sex'])
    #     # print(kwargs['hobby'])
    #
    # test2(name='lieying',age=22,sex='man',hobby='gril')
    # test2(**{'name':'alex','age':8})
    #
    # def test3(name,**kwargs):
    #     print(name)
    #     print(kwargs)
    # test3('alex',age=18,sex='m')

    # def test4(name,age=18,**kwargs):
    #     print(name)
    #     print(age)
    #     print(kwargs)
    #
    # test4('alex',age=34,sex='m',hobby='tesla')
    def logger(source):
        print("from %s" % source)
    def test4(name,age=18,*args,**kwargs):
        print(name)
        print(age)
        print(args)
        print(kwargs)
        logger("TEST4")


    test4('alex',age=34,sex='m',hobby='tesla')

    1.8 高阶函数 意思是函数里套函数

    def add(a,b,f):
        return f(a)+f(b)
    res = add(3,-6,abs)
    print(res)

    1.8.1 高阶函数

    def add(a,b,f):
        return f(a)+f(b)
    res = add(3,-6,abs)
    print(res)

    D:python3.6python.exe C:/Users/Administrator/PycharmProjects/python18期/day2/高阶函数.py

    9

    1.8.2 递归

    有明确的结束条件 python默认可以999层

    问题规模每递归一次都应该比上一次的问题规模有所减少

    效率低

    def calc(n):
        print(n)
        if int(n/2)>0:
            return calc( int(n/2) )
        print('->',n)
    calc(10)

    1.9 函数式编程

    是没有变量的

    1.10 匿名函数

    calc =lambda x:x*3

    calc()

    第2章 Day4

    装饰器:

    定义 本质是函数,(装饰其他函数)就是为其他函数添加附加功能

    原则:

    1,不能修改被装饰的函数的源代码

    2,不能修改被装饰的函数的调用方式

    门牌号都没有的时候(没有引用的时候) 内存存的值就会被释放回收  这就是垃圾回收

    del x 删除的是变量名 不是变量值

    函数先定义 再调用

    没定义 调用就会报错

    2.1 高阶函数

    2.1.1 a:把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)

    实例2-1   

    import time
    def bar():
        time.sleep(3)
        print('in the bar')
    def test(func):
        start_time=time.time()
        func()
        stop_time=time.time()
        print('the func run time is %s' %(stop_time -  start_time))
    test(bar)

    2.1.2 b:返回值中包含函数名(不修改函数的调用方式)

    import time

    def bar():

        time.sleep(3)

        print('in the bar')

    def test2(func):

        print(func)

        return func

    # print(test2(bar))

    bar=test2(bar)#把bar的内存地址传给bar

    bar()  #run bar

    2.2 嵌套函数

    def foo():

        print('in the foo')

        def bar():

            print('in the bar')

        bar()

    foo()

    2.3 高阶函数+嵌套函数=》》装饰器

    '''import time
    def deco(func):
        start_time=time.time()
        func()
        stop_time=time.time()
        print(stop_time-start_time)
    def test1():
        time.sleep(3)
        print('in the test1')
    def test2():
        time.sleep(3)
        print('in the test2')
    deco(test1)
    deco(test2)
    ''' 
    #利用高阶函数实现了功能但是 改变了原函数的调用方式


    #接下来我们加一层嵌套函数 看能否不改变调用方式能否实现新加功能
    import time
    def timer(func):  #   timer(test1)  func=test1
       
    def deco():
            start_time=time.time()
            func()  #  run test1()
           
    stop_time=time.time()
            print('run time is %s'%(stop_time-start_time))
        return deco
    @timer  # test1=timer(test1)
    def test1():   
       
    time.sleep(3)
        print('in the test1')
    @timer # test2=timer(test2)
    def test2():  
       
    time.sleep(3)
        print('in the test2')
    #print(timer(test1))
    # test1=timer(test1)
    # test2=timer(test2)
    test1()
    test2()
    # deco(test1)
    # deco(test2)

    2.4 装饰器高潮版

    2.5 列表生成式

    >>>L = [x * 2 for x in range(10)]

    >>> L

    [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

    >>> g=(x * 2 for x in range(10))

    >>> g

    <generator object <genexpr> at 0x02CC5F80>

    >>> for i in g:

       print(i)

      

    0

    2

    4

    6

    8

    10

    12

    14

    16

    18

    >>> a= [ i for i in range(10)]

    >>> a = map(lambda x:x+1, a)

    >>> a

    <map object at 0x02F66AD0>

    >>> for i in a:print(i)

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    生成器只会在调用的时候才会生成相应的数据

    只记录当前的位置只有一个__next__()方法。next()

    [1,2,3,4,5,6,7,8,9]

    2.6 斐波那契数列

    def fib(max):
        n,a,b =0,0,1
        while n< max:
            yield b
            a,b =b,a+b
            n=n+1
        return '---done--' #异常的时候打印的消息
    # fib(10)
    # for n in fib(10):
    #     print(n)
    g=fib(10)
    while True:
        try:
            x = next(g)
            print('g:',x)
        except StopIteration as e:
            print('Generator return value:',e)
            break
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__())
    next 方法到没数据时会报错

    如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

    2.7 迭代对象

    可以直接用于for循环的对象统称为可迭代对象 Iterable

    一类是集合数据类型,如list、tuple、dict、set、str等

    一类是generator,包括生成器和带yield的generator function

    可以使用isinstance()判断一个对象是否是Iterable对象:

    >>> from collections import Iterable

    >>> isinstance([],Iterable)

    True

    >>> isinstance({},Iterable)

    True

    >>> isinstance('abc',Iterable)

    True

    >>> isinstance((x for x in range(10)),Iterable)

    True

    >>> isinstance(100,Iterable)

    False

    2.8 迭代器

    而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

    *可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

    可以使用isinstance()判断一个对象是否是Iterator对象:

    >>> from collections import Iterator

    >>> isinstance((x for x in range(10)), Iterator)

    True

    >>> isinstance([], Iterator)

    False

    >>> isinstance({}, Iterator)

    False

    >>> isinstance('abc', Iterator)

    False

    >>> 

    生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。

    把list、dict、str等Iterable变成Iterator可以使用iter()函数:

    >>> isinstance(iter([]), Iterator)

    True

    >>> isinstance(iter({}), Iterator)

    True

    >>> isinstance(iter('abc'), Iterator)

    True

    你可能会问,为什么list、dict、str等数据类型不是Iterator?

    这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

    小结

    凡是可作用于for循环的对象都是Iterable类型;

    凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

    集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

    or甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

    Python的for循环本质上就是通过不断调用next()函数实现的,例如:

    for x in [1, 2, 3, 4, 5]:

        pass

    # 首先获得Iterator对象:
    it = iter([1, 2, 3, 4, 5])
    # 循环:
    while True:
        try:
            # 获得下一个值:
            x = next(it)
        except StopIteration:
            # 遇到StopIteration就退出循环
            break
  • 相关阅读:
    商人的诀窍 结构体
    商人的诀窍 结构体
    小泉的难题 结构体
    小泉的难题 结构体
    来淄博旅游 结构体
    来淄博旅游 结构体
    分类游戏 结构体
    7月20日学习
    7月19日学习
    7月18日学习
  • 原文地址:https://www.cnblogs.com/lieying6011/p/7199433.html
Copyright © 2011-2022 走看看