Python笔记(三)

##第四章
4-1 函数—定义/参数/返回值
函数:
函数是程序对逻辑进化结构化的一种编程方法,使用代码块对逻辑进行隔离,方便代码读写和修改。
Pyhton函数定义:
关键字def + 函数名 + (参数) + :
process..

    def foo():            def add(x,y):
        pass                return x + y

    python函数也是对象,函数也有相应的属性。
    dir(foo)

参数:
    形参/关键字参数/默认参数:
        形参:函数被调用,传入的参数必须和函数定义参数位置个数一致。

        关键字参数:关键字参数针对函数调用,这种调用方式可以让调用者使用参数名来区分参数,
        这种调用方式可以语序参数不按顺序,Python解释器会通过关键字来匹配参数的值。

        默认参数:默认参数声明默认值的参数,如果函数调用过程中,可以不传递该参数。

        形参/关键字参数                 默认参数:
        def _power(x,y):            def _power(x = 2, y = 1):
            return x*y                    return x*y

        _power(2,3) = 6                _power() = 2
        _power(y = 3,x = 2) = 6
    可变长度参数函数:
        可变长度参数函数声明中不能被显示命名,以为参数的数目在运行前或者在程序运行中是未知的。

        非关键字可变长度参数(元组):
            def func(formal_args,*vargs_args):
                pass
            form_args:函数被调用时,非可变参数赋值给函数声明中的局部变量。
            vargs_args:函数调用时,非关键参数按顺序插入到一个元组中,方便访问。

        关键字可变长度参数(字典):
            def func(formal_ars,**vargsed):pass
            formal_args:函数被调用时,非可变参数赋值给函数声明的局部变量。
            **vargsed:函数被调用时,不定数目的关键字参数,放到一个字典中,键为参数名,值为相对应的参数值。
    函数返回值:
        如果没有显示返回值,返回None
        如果函数返回值只有一个,那么返回该对象
        如果函数返回值有多个,那么返回一个元组
        返回值是序列或者字典,接收返回值方式不同,处理方式也不同。

    Python中,函数的声明和定义是一起的。

    def foo():
        bnar()

    def bar():
        print "in bar()"
    foo()

    首先声明foo()函数,然后声明了bar()函数,当我们调用foo()函数的时候,
    bar()函数已经存在,所以在foo()中可以调用bar成功。

4-2 函数—作用域/全局变量/局部变量
Python作用域:
local:比如function中的变量所在的作用域就是local
enclosing:某个function被嵌套后的上一层function的作用域
global:当前模块中的全局作用域
built-in:Python内置作用域

    python变量作用域:由变量在代码中定义位置决定
        x = 10
        def foo():
            print(x)
            x = 1
        foo()
    这个程序执行结果:报错。
    x = 1 和print(x)位置互换执行结果:1

    python中的if/else/elseif/try/for/while语句不会修改变量作用域。

变量查找顺序:本地 > 外部 > 全局 > 内置
    x = 10
    z = 10
    def foo():
        x = 5
        y = 1
        def bar():
            print("x = %d y = %d z = %d" % (x,y,z))
        return bar
    foo()()

    1.从本地变量查找(bar()的作用域)
    2.从外部作用域查找(foo()的作用域)
    3.从全局作用域查找(当前模块)

    在函数中修改全局变量 global x
    在内置函数中声明外部函数的局部变量,可以修改 nonlocal x

4-3 函数—函数式编程
函数式编程:
函数能够接受输入并产生输出
优点:
1.代码复用,编码效率更高,维护方便
2.易于测试和调试
3.模块化,代码更加容易组织
4.封装,多人开发中,保证自己代码不被别人修改
5.双方合作,为了保护核心代码,可以提供Python库和接口
4-4 函数—匿名函数和内置函数
匿名函数可以用lambda关键字来创建,一条完整的lambda语句是一个完整的表达式,
返回的值是一个可以调用的函数对象。
基本语法:lambda arg1,arg2…argN:process
实列:lambda x,y:return x + y
lambda : True
lambda:
1.调用lambda产生的函数对象和调用普通的函数对象类似
foo = lambda x,y: return x*y
bar = lambda *x : x
dic = lambda *
x:x
2.可以被当作参数传递给函数
def bar(foo):
return foo(2,3)
3.可以使用参数(形参、关键字参数、默认参数、不定长参数)
foo(2,3); foo(y=2,x=3); bar(1,2,3,4);dic(x=10,y=20)

lambda和函数对比:
    def add(x,y):        add = lambda x,y:x+y
        return x+y <==>                        <==>a = 1 + 1
    a = add(1,1)        a = add(1,1)
lambda表达式作为返回值:
    def foo(x):            
        return lambda y: x + y
    add = foo(10)
    sum = add(10)
    sum = 20
lambda和列表解析使用:
list_foo = [lambda x: x+n for n in range(10)]
list_foo返回的其实是列表函数也就是每一个元素是函数,
比如0号元素是lambda x:x
list_foo[0](10) = 10
list_foo[1](10) = 11
list_foo[8](10) = 18

分析列表解析过程:
    list_foo = [lambda x:x+n for n in range(10)]
    1.首先for循环引入了全局变量n
    2.产生一个函数列表:[lambda x: x+n]
    3.list_foo[0](10)->lambda:x+n -> 10+n(n是全局白能量,当列表解析完成后,n=9)
    所以这个列表所有函数都等于:
        def foo(x):return x+n
修改列表解析:
    list_foo = [lambda x,n=n:x+n for in range(10)]
    结果:
    list_foo[0](10) = 10
    list_foo[1](10) = 11

    函数列表内容:
    lambda 创建函数的时候引入了默认参数n=n,左边这个n是参数,是函数中的局部变量,
    右边n是列表解析过程中的实际值。
了解函数的map(function,sequence[,sequence,...]):
          reduce(function,sqeuence[,initial]):
          filter(function or None,sequence):
偏函数:讲函数某个参数固定,并且返回一个新的函数
    from functools import partial
        语法:partial(func,*args,**keywords)
    偏函数示例:
        讲字符串转化整数(16进制):int("256",16)
        使用偏函数:int16 = partial(int,base=16)
        int16('256')=>转化为10进制的
    partical实质创建并返回一个新的函数:
        def int16(x):
            return int(x,16)

4-5 函数—函数闭包/装饰器/生成器
闭包:在内部函数中,对外部作用域的变量进行引用,那么这个函数就是闭包。
示例:
def bar(base):
def in_bar(offset):
return base +offset
return in_bar
in_bar()函数引入了外部变量base,使用in_bar()函数就是闭包,当我们调用bar()的时候
返回给我们in_bar()函数,这个in_bar函数就是一个闭包
当我们调用bar(),传入base值,就是外部作用域变量

闭包的作用:
    提供数据封装,我们传给闭包一个属性,闭包给我们提供一个调用接口,
    代码复用,简化代码。

装饰器:
    是一个包装函数的函数,返回一个修改后的函数对象,把函数重新赋值,
    返回给原来的标识符,并丧失对原始函数对象的访问。
装饰器基本语法:
    @deco(deco_args)        #deco返回值为函数的函数
    def func(func_args):    #func有参或者无参
        pass
    实际结果:func = deco(func)
多重装饰器:deco1和deco2都是
          @deco1
          @deco2
          def func(arg):
                  pass
    其实就是:func = deco1(deco2(func))
这里是理解的难点,举一个示例。
def deco(func):                  def deco(func):
    print("in deco()")              print("in deco()")
    func()            使用装饰器     return func
                               @deco
def bar():            ---》 》 》        def bar():
    print("in bar")                    print("in bar")

deco(bar)                       bar()
前者并没有装饰效果,因为直接返回了func。

装饰器修改一个函数:
    def deco(func):
        print("in deco()")
        def foo():
            print("befor call func()")
            func()
            print("after call func()")
        return foo

    print("befor deco bar")
    @deco
    def bar():
        print("in bar")
    print("after call bar")

    bar()
上述代码执行过程:
    装饰器把foo函数返回给bar这个名字,deco的参数func是外部变量,foo调用func的时候
    其实是原来的bar函数,foo函数也就是一个闭包。当我们在调用bar函数的时候,
    类似于原来调用deco(bar)(),
    deco中的foo前面代码只执行一次,因为foo前面代码是外部作用域。

带参数的装饰器在调用的时候需要传入参数。本质上没差异

生成器:
    一个函数,函数的参数都会保存,当他返回时会记录代码执行到该函数位置。
    再次调用生成器函数会直接跳转之前位置,而且上次调用的所有局部变量不变。

python生成器:
    是一个带yield关键字的函数,yield能够返回给调用者一个结果,并且暂时执行,
    当调用者使用next()再次调用的时候,他会从yield后面语句继续执行。
python生成器语法: def gen():yield
示例and分析过程:
def generators():        gen = generators(): 结果:
    yield         >>>    gen.next()            None
    yield 10            gen.next()            10
    yield 20            gen.next()            20
                        gen.next()            StopIteration
    第一次调用:记录当前代码执行位置并返回None
    第二次调用:从上一次记录的位置开始执行,记录当前位置,返回10
    第三次调用:从上一次记录的位置开始记录当前位置,返回20
    第四次调用:没值了所以会报一个异常。

生成器使用:找出给定范围内的偶数
    def gen_even(max):
        n = 0
        whlie(n < max):
                if(n % 2 == 0):
                    yield n
                n++

    even = gen_even(100)
    even.next()...(这里可以用循环语句输出)

##参考视频
奇猫的Python教学视频

作者 Luckyboy

Reward
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • © 2015-2020 John Doe
  • Powered by Hexo Theme Ayer
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信