命名空间、闭包、上下文管理器、鸭子类型与多态(10)

第10章 Python进阶话题

函数与命名空间

函数的全局命名空间始终是定义该函数的模块,而不是调用该函数的命名空间。
函数及其全局命名空间决定了函数中引用全局变量的值

因此,在函数中引用的全局变量始终是定义该函数模块中的全局变量


闭包及其应用(嵌套函数)
闭包:将组成函数的语句和这些语句的执行环境打包到一起所得到的对象。当使用嵌套函数时,闭包将捕获内部函数执行所需的整个环境。

嵌套的函数可以使用被嵌套函数中的任何变量,就像普通函数可以引用全局变量一样,而不需要通过参数引入。

闭包的应用是根据嵌套函数持有定义环境变量的特性来完成功能的

闭包:
def foo():
    x=3
    def bar():
        print('x is %d'%x)
    bar()

闭包与延迟求值:闭包可以实现先将参数传递给一个函数,而并不立即运行,以达到延迟求职的目的。
所谓延迟求值,就是函数返回的是一个函数,而真正需要运行函数中的代码时,其本质还是函数调用。

例:
def delay_fun(x,y):
    def calculator():
        return x+y
    return calculator
if __name__=='__main__':
    print('返回一个求和的函数,并不求和。')
    msum=delay_fun(3,4)
    print()
    print('调用并求和:')
    print(msum())

闭包与泛型函数

例:实现所有类型的一次函数的求值
def line(a,b):
    def aline(x):
        return a*x+b
    return aline
if __name__=='__main__':
    line23=line(2,3)
    line50=line(5,0)
    print(line23(4))
    print(line50(2))

上下文管理器:实现上下文管理协议方法的对象,方便资源管理的一种语法形式。
上下文协议方法:
__enter__(self)          #该方法是进入上下文时调用的,它创建并返回一个可以引用的资源对象,供with语句块中的程序使用
__exit__(self,type,value,tb)   #该方法是推出上下文时调用的,主要用来安全地释放资源对象。参数type、value、tb用于跟踪退出错误时发生的错误类型、值和跟踪信息。

使用上下文管理器的with语句的形式为:
    with context as var:
        pass
变量var将取得上下文管理器的__enter__()方法所返回的资源引用,供with后的代码块中使用

例:
class FileMgr:
    def __init__(self,filename):
        self.filename=filename
        self.f=None
    def __enter__(self):
        self.f=open(self.filename,encoding='utf-8')
        return self.f
    def __exit__(self,t,v,tb):
        if self.f:
            self.f.close()
if __name__=='__main__':
    with FileMgr('10-4.py') as f:
        for line in f.readlines():
            print(lines,end='')

使用这个管理文件的上下文管理器后,在每次使用文件资源时都不用写打开关闭文件的代码,就像操作一般变量一样操作就行了。

contextmanager——将生成器转变为上下文管理器的装饰器
例:
import contextlib   #内置的上下文管理器的模块
@contextlib.contextmanager
def my_mgr(s,e):
   print(s)
   yield s+' '+e
   print(e)
if __name__=='__main__':
   with my_mgr('start','end') as val:
       print(val)


用字符串操作对象的属性(略)

用字典构造分支程序(略)


重写类的特殊方法:
__init__  构造函数,生成对象时调用
__del__ 析构函数,释放对象时调用
__add__ 加运算
__mul__ 乘运算
__cmp__ 比较
__repr__  打印,转换
__setitem__  按照索引赋值
__getitem__   按照索引获取值
__len__       获得长度
__call__      函数调用


鸭子类型与多态:
鸭子类型(duck typing)是动态类型的一种风格,在这种风格中,一个对象有效的语义不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定

“当看到一只鸟走起来像鸭子、游泳起来像鸭子,叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。
在鸭子类型的语言中,编写一个函数可以接受一个任意类型的对象,并调用它的走和叫的方法。任何拥有这样的正确的走和叫方法的对象都可被函数接受。

例:
class Duck:
    def __init__(self,name='duck'):
        self.name=name
    def quack(self):
        print("gagaga....")
class Cat:
    def __init__(self,name='cat')
        self.name=name
    def quack(self):
        print("miaomiaomiao....")
class Tree:
    def __init__(self,name='tree')
        self.name=name
def duck_demo(obj):
    obj.quack()
if __name__=='__main__':
    duck=Duck()
    cat=Cat()
    tree=Tree()
    duck_demo(duck)
    duck_demo(cat)
    duck_demo(tree)  #报错

posted @ 2016-08-15 15:32  魔沫  阅读(257)  评论(0编辑  收藏  举报