Python全栈之路-Day32

1 类的__slots__

#!/usr/bin/env python
# __Author__: "wanyongzhen"
# Date: 2017/4/25

# 只能定义__slots__中规定的属性
#__slots__  用于统一管理所有属性的定义
# 类变量,变量值可以是列表,元祖,或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性)
class People:
    __slots__ = ['x','y','z']

p = People()
p.x = 1
p.y = 2
p.z = 3
print(p.x,p.y,p.z)
p.v = 4 # 会抛出AttributeError异常

2 迭代器协议

#!/usr/bin/env python
# __Author__: "wanyongzhen"
# Date: 2017/4/25

# __next__ __iter__
from collections import Iterable,Iterator
class Foo:
    def __init__(self,start):
        self.start = start

    def __iter__(self):
        return self

    def __next__(self):
        if self.start > 10:
            raise StopIteration
        num = self.start
        self.start += 1
        return num

f = Foo(0)
print(isinstance(f,Iterable))
print(isinstance(f,Iterator))
print(next(f))
print(next(f))
for item in f:
    print(item)
# 利用迭代特性实现简单的range函数功能
class Range:
    def __init__(self,start,end):
        self.start = start
        self.end = end

    def __iter__(self):
        return self
    def __next__(self):
        if self.start > self.end:
            raise StopIteration
        num = self.start
        self.start += 1
        return num

for item in Range(0,2):
    print(item)

3 类的__del__

#!/usr/bin/env python
# __Author__: "wanyongzhen"
# Date: 2017/4/25

import time
class Open:
    def __init__(self,filepath,mode='r',encode='utf-8'):
        self.f = open(filepath,mode,encoding=encode)

    def write(self):
        pass
    def __getattr__(self, item):
        return getattr(self.f,item)
    def __del__(self):  # 当执行del f(并且引用计数为0时)时会触发这里的函数运行(程序结束时也会运行),一般执行一些清理操作
        print('del func')
        self.f.close()

f = Open('a.txt','w')
del f
time.sleep(5)

4 上下文管理协议

#!/usr/bin/env python
# __Author__: "wanyongzhen"
# Date: 2017/4/25

with open('a.txt','r') as f:
    print('--------->')
    print('--------->')
    print(f.read())

class Foo:
    def __enter__(self):
        print('enter...')
        return self
    def __exit__(self, exc_type, exc_val, exc_tb): # with代码块结束或者出现异常时执行
        print('exit...')
        print('exc_type',exc_type)
        print('exc_val',exc_val)
        print('exc_tb',exc_tb)
        return True  # 处理异常后返回True
with Foo() as f:  # f = Foo().__enter__()
    print('with Foo code area')
    raise TypeError('Error value') # 会调用__exit__

5 元类

#!/usr/bin/env python
# __Author__: "wanyongzhen"
# Date: 2017/4/26

# 元类 type
# 元类(type) --> 类(class) --> 对象(object)
# 1.通常的创建类的方式
class Foo:  #
    x = 1
    def run(self):
        pass
class test:
    pass

print(Foo.__dict__)
print(Foo.__bases__)
print(type(Foo))

# 2.通过元类(type)创建类的方式
def run():
    pass
class_name = 'Foo'
class_bases = (object,)
class_dict = {'x':1,'run':run}
Foo = type(class_name,class_bases,class_dict)

print(Foo.__dict__)
print(Foo.__bases__)
print(type(Foo))

# 元类应用
# 类的函数必须要写注释(__doc__)
class Mymeta(type):
    def __init__(self,class_name,class_bases,class_dict):
        for key in class_dict:
            if callable(class_dict[key]):
                if not class_dict[key].__doc__:
                    raise TypeError('小子,你没写注释,赶紧去写')

class Foo(metaclass=Mymeta):  # Foo = Mymeta('Foo',(object,),{'x':1,'run':run}) 定义时会执行metaclass的__init__
    x = 1
    def __init__(self,name):
        self.name = name
    def run(self):
        'run func'
        print('running')

print(Foo.__dict__)

# 元类实例化过程
class Mymeta(type):
    def __init__(self,class_name,class_bases,class_dict):
        for key in class_dict:
            pass
    def __call__(self, *args, **kwargs):
        print(self)
        obj = self.__new__(self)
        self.__init__(obj,*args,**kwargs)
        return obj

class Foo(metaclass=Mymeta):  # Foo = Mymeta('Foo',(object,),{'x':1,'__init__':__init__,'run':run})  调用Mymeta的__init__ 
    x = 1
    def __init__(self,name):
        self.name = name
    def run(self):
        'run func'
        print('running')

f = Foo('egon')  # 调用Mymeta的__call__ 

posted on 2017-04-25 22:07  万越天  阅读(99)  评论(0编辑  收藏  举报