一.昨日内容回顾
1.反射
用字符串类型的名字,操作命名空间的变量。
反射使用场景:明显的简化代码,能拿到的变量名本来就是一个字符串类型的时候,
用户输入的,文件读入的,网上传输的
2.__call__
对象名() 就会调用__call__方法
3.__len__
4.__hash__
5.__eq__
6.__dict__
对象名.__dict__:查看对象空间的变量的变量,
类名.__dict__ 类空间
7.__slots__
#__slots__ = ('name','age')
8.__module__和__class__
9.isinstance和issubclass
二.今日内容总结
1.__new__
#创建一个对象,是一个构造方法,在初始化方法__init__(self,...)执行之前执行。
单例模式:

class A: __instance = None def __init__(self,name): self.name = name def __new__(cls, *args, **kwargs): if not cls.__instance: cls.__instance = object.__new__(cls) return cls.__instance a = A('alex') b = A('jack') print(a.name) print(b.name)
2.__del__
#在一个对象在内存中删除前,执行__del__方法
# 对比delattr 使用字符类型的变量从命名空间中删除这个变量
# 对比@property deleter 伪装成属性的方法,要执行删除属性
#Python解释器
#能够主动回收不用的变量
#在程序结束的时候所有的数据都会被清除
#如果用户主动删除某个变量
# 那么这个变量将会主动的被删除
#无论上述哪种方式
#在删除一个变量之前都会主动的执行析构方法__del__
应用:对象删除之前回归操作系统资源
class B:
def __init__(self,path):
self.f = open(path)
def __del__(self):
self.f.close()
b = B('userinfl')
3.__getitem__、__setitem__、__delitem__
# 有一些内置模块中的内置方法
#是依赖__getitem__方法的
#或者说是依赖item['a']这种调用方式的
# 洗牌,抽牌例子:
random.choice方法依赖(__len__,__getitem__)
random.shuffle方法依赖作用对象还有内置方(__len__,__getitem__,__setitem__)

import random from collections import namedtuple Card = namedtuple('card', ['rank', 'suit']) class FranchDeck: ranks = [i for i in range(2, 11)] + list('JQKA') suits = ['红心', '方块', '黑桃', '梅花'] def __init__(self): self.__cards = [Card(rank, suit) for rank in FranchDeck.ranks for suit in FranchDeck.suits] def __len__(self): return len(self.__cards) def __getitem__(self, item): return self.__cards[item] def __setitem__(self, key, value): self.__cards[key] = value def __delitem__(self, key): del self.__cards[key] deck = FranchDeck() print(deck.__dict__) print(deck[0]) random.shuffle(deck) print(deck.__dict__) print(random.choice(deck))
4.异常处理
#try except
#try except else
#try except else finally
#try finally
# assert 1=2
# raise 主动抛出异常
# 自定义异常类型

class WuException(BaseException): def __init__(self, name): self.__name = name def __str__(self): return self.__name try: raise WuException('有东西错了试试吧') except WuException as e: print(e)
三.预习与扩展
1.对元类metaclass的理解:
1)、我们用class关键字创建的类,都是通过基类type类创建:
class Foo(object):
a = 1
def func():
print(6666)
等同于:type('Foo',(object,),{'a':1,‘func’:func})
def func():
print(6666)
2) 、 创建类的时候有优先找__metaclass__,自己没有找父类,父类没有找模块,一直找不到就会利用内置type进行类的创建
class A:
__metaclass__ = mm
3)、我们自己定制元类:
class metaclasstest(type):
def __new__(cls,name,bases,dict):
..........
return super().__new__(cls,name,bases,dict(可变化))
2.内置方法的小结:

class A: name = 'jack' def __init__(self): super().__init__() def __getattr__(self, item): print('getattr没有该属性%s' % item) def __delattr__(self, item): del self.__dict__[item] def __setattr__(self, key, value): self.__dict__[key] = value # def __getattribute__(self, item): # print('getattribute %s 不知道没有该属性' % item) # __getattr__ 调用没有属性时触发 a.age # __setattr__ 添加属性时触发 a.age = 1 # __delattr__ 删除属性时触发 del a.age # __getattribute__ 调用时有没有属性时都会触发 a.age # -----------------------------------------*--------------------------------------- # 当重写__getattribute__时,别的函数不在执行而是执行__getattribute__ a = A() a.age a.age = 1 print(a.__dict__)