16、Python中的闭包、上下文、类的专有方法及鸭子类型


1、函数和命名空间

函数的全局命名空间始终是定义该函数的模块,而不是调用该函数的命名空间。因此,在函数中引用的全局变量始终是定义该函数模块中的全局变量。


2、闭包及其应用

闭包是指Python中组成函数的语句和这些语句的执行环境打包到一起所得的对象;

闭包的应用有如下两种:

  • 延迟求值
  • 泛函数

(1)、闭包与延迟求值

延迟求值示例:

def function(x, y):
    def fun():
        return x + y
    return fun;

if __name__ == '__main__':
    testfun = function(10, 20)

    print('The Result Is', testfun())

运行结果:
The Result Is 30

(2)、闭包与泛函数

泛函数示例:

def function2(x, y):
    def aline(a):
        return a * x + y
    return aline

if __name__ == '__main__':
    aline1 = function2(10, 20)
    aline2 = function2(3, 7)

    print('The Result1 Is', aline1(2))
    print('The Result2 Is', aline2(3))

运行结果:
The Result1 Is 40
The Result2 Is 16


3、上下文管理器

上下文管理器是指实现上下文管理协议方法的对象,它主要用于安全地释放资源;
with 语句中使用上下文管理器或提供资源,当退出with语句时上下文管理器负责安全释放

上下文管理器的协议方法有下面两个:

  • __enter__(self): 创建并返回一个可引用的资源对象
  • __exit__(self, type, value, tb) : 退出上下文时,安全释放资源对象。

上下文管理器示例:

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('G:\\work\\python\\ClassTest.py') as f:
        for line in f.readlines():
            print(line, end='')

运行结果:
G:\work\python\ClassTest.py文件中的内容


4、函数操作对象属性

python内建函数:hasattr()和setattr()

hasattr()函数,可以测试对象是否含有某个属性

  • hasattr(object, name)
  • object: 被测试对象(类或函数等)
  • name:函数名(字符串格式)

setattr()函数,可以设置某个函数对象属性值,设置可以添加属性并赋值

  • setattr(object, name, value)
  • object: 要设置的对象(类或函数等)
  • name:要设置的属性名(字符串格式)
  • value: 要设置的属性值

示例:

class PosInfo:
    def __init__(self, x=10, y=20):
        self.x = x
        self.y = y
    def info(self):
        print('x is', self.x)
        print('y is', self.y)
        print('value', self.value)

if __name__ == '__main__':
    pos = PosInfo()
    if not hasattr(PosInfo, 'x'):
        setattr(PosInfo, 'x', 100)
    if not hasattr(PosInfo, 'y'):
        setattr(PosInfo, 'y', 200)
    if not hasattr(PosInfo, 'value'):
        setattr(PosInfo, 'value', 20)

    pos.info()

运行结果:
x is 10
y is 20
value 20


5、重载类的特殊方法

在python中,类有一些以两条下划线开始并且以两条下划线结束的方法,成为类的专有方法。

部分类的专有方法,如下:

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

6、鸭子类型(duck typing)和多态

python语言属于动态类型语言,所以变量的类型是不确定的。鸭子类型是动态类型的一种风格,一个对象有效的语义不是有继承自特定的类型或实现特定的接口,而是由当前的属性和方法集合决定。

示例:

class Duck:
    def __init__(self, name='duck'):
        self.name = name

    def quack(self):
        print('嘎嘎嘎!')

class Cat:
    def __init__(self, name='cat'):
        self.name = name
    def quack(self):
        print('喵喵喵!')

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)        #运行出错

运行结果:
嘎嘎嘎!
喵喵喵!

猜你喜欢

转载自blog.csdn.net/douzhq/article/details/79346508