面向对象进阶博客地址链接:
http://www.cnblogs.com/Eva-J/articles/7351812.html
复习昨日内容:
# 包# 开发规范 ## hashlib # 登录验证 密文密码检测 # 密文存储 # 加盐 # 动态加盐 # 检测文件一致性 md5 #MD5.update()# configparser : 配置文件相关 #网络编程 ftp #[section1] #o1 = yes# logging : 日志 #记录一些信息和结果 #打日志 #日志就和print #学生管理系统 #需要用户选择的时候打印的提示信息 #一个程序和用户发生文字交互的时候,不能使用logging # 中间结果 错误提示 都可以使用logging # 管理员在某时某刻创建了一个班级 —— logging
今日概要:
# 欠你得内置函数 ***# 反射 *****# 类的内置双下方法 ***# 面向对象的高级代码和一道面试题 # 看书 # 看源码 # 看博客 #简书 #csdn
内置函数:
#property#classmethod#staticmethod#super#object#isinstance#issubclass#vars# from collections import Iterable# print(isinstance([],Iterable))# class A:pass# class B(A):pass# b = B()# print(isinstance(b,A))# print(isinstance(a,object))# class A:pass# class B(A):pass# print(issubclass(B,A))# print(issubclass(A,B))# print(issubclass(A,object))# print(issubclass(B,object))#isinstance(对象,类) 判断这个对象是不是这个类或者这个类的子类的实例化#看全局# a = 1# b = 2# print(vars())# print(dir())class A: ''' 描述管理员的类 ''' c = 1 d = 2 def func(self,name): ''' 这个函数整体是做什么的 :param name: 管理员的姓名 :return: 管理员的信息 ''' self.name = 'alex'#看类# print(vars(A))a = A()a.func()#看对象print(vars(a))''' 这个函数的主要功能 :return: '''
反射:这个很重要,必须要学会!
# hasattr()# getattr()# setattr()# delattr()# a = 1# name = 'a'# print(vars())# print(vars()[name])# eval()class Management: role = '管理员' def __init__(self,name,sex,phone,mail): self.name = name self.sex = sex self.phone = phone self.mail = mail def creat_class(self): print('创建了一个班级') def creat_teacher(self): print('新建了一条讲师信息') def creat_student(self): print('新建了一条学生信息')# Management.role# if hasattr(Management,'role'):# print(getattr(Management,'role'))# import logging# manager = Management('小雨','女',1233211234567,'xiaoyu@qq.com')# if hasattr(manager,'sex1'):# sex = getattr(manager,'sex1') #使用字符串数据类型的变量名获取属性值# print(sex)# else:# logging.warning('没有您输入的属性')# cs = getattr(manager,'creat_class') #使用字符串数据类型的方法名调用方法# cs()# Management.Country = 'China'# setattr(Management,'Country','China')# print(Management.Country)# del Management.Country# delattr(Management,'Country')# print(Management.Country)# manager = Management('小雨','女',1233211234567,'xiaoyu@qq.com')# manager.hobby = '点名'# setattr(manager,'hobby','点名')# print(manager.hobby)#可以通过delattr删除一个类中的方法# delattr(Management,'creat_class')# manager.creat_class()# def create_course(self):# print('创建了一个课程')# setattr(manager,'create_course',create_course)# manager.create_course(manager)# hasattr(对象名,'属性名') 返回True或False#属性值 = getattr(对象名,'属性名')#方法的内存地址 = getattr(对象名,'方法名')#方法的内存地址()# import demo# # demo.a# print(getattr(demo,'a'))# qq = getattr(demo,'qqxing')# ret = qq('wahaha')# print(ret)# aaa = 'bbb'# import sys# print(sys.modules[__name__])# print(getattr(sys.modules[__name__],'aaa'))# 对象的反射# 类的反射# 模块的反射# 本模块的反射 : 找到本模块sys.modules[__name__]
反射包括在类中对象的反射,类的反射,以及模块的反射,还有程序所处当前位置的本模块的反射。
类的内置方法:
#str 和 repr# class A:# # pass# def __str__(self):# return 'A的对象' # def __repr__(self): # return 'repr: A的对象'# a = A()# print(a) #本质调用的是__str__,如果没实现,就调用__repr__, 再找不到,用object父类的# print(a.__str__()) #str却不能给repr做备胎# print(a.__repr__()) #repr是str的备胎# 打印一个对象的时候,实际上是调用了这个对象所在类的__str__方法,打印的是这个方法的返回值# print(str(a))# print(repr(a))# print('%s'%a)# print('%r'%a)# print(a)# l = list()# print(l)# format_dict={ # 'nat':'{o.name}-{o.addr}-{o.type}',#学校名-学校地址-学校类型# 'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址# 'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名# }# class School:# def __init__(self,name,addr,type):# self.name=name# self.addr=addr# self.type=type## def __format__(self, format_spec): #format_spec = 'nat'# fmt='''=====================# 姓名 : {obj.name}# 班级 : {obj.addr}# ====================='''# return fmt.format(obj=self)# s1=School('oldboy1','北京','私立')# print(format(s1,'nat'))# print(format(s1,'tna'))# print(format(s1,'tan'))# print(format(s1,'asfdasdffd'))#打印学生信息#姓名 班级 性别 年龄#=====================# 姓名 : name# 班级 : class#=====================# 析构方法# 周期 :0# 12 一个亿个对象 del 对象# class A:# def __del__(self):# '''# 析构方法# 这个方法只有在执行del A类的对象的时候才被触发# 且先执行代码中的内容,再删除对象# 如果我删除了这个对象,它跟着还有一些其他的附属的内容也没有用了# 我们就可以在这个方法中回收掉# '''# print('执行我啦!')# self.b.close()# f = open('file','w')# a = A()# a.b = f# del a# print(a)class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): if item == 1: print('hahaha') # print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key]=value def __delitem__(self, key): print('del obj[key]时,我执行') self.__dict__.pop(key) def __delattr__(self, item): print('del obj.key时,我执行') self.__dict__.pop(item)f1 = Foo('sb')#访问属性的方式变了#对象名.属性# f1=Foo('sb')# f1['age']=18 #给f1添加一个属性# del f1['age'] #删除属性# # f1.name# print(f1['name'])## f1.__dict__['age'] = 18# f1['age1']=19# del f1.age1 #删除属性## f1['name']='alex'# print(f1.__dict__)#pytho内部的约定#关于item : 对象访问 如果是 对象名[],是因为内部实现了item系列的方法# 对象的实例化 #创造一个裸地对象 —— __new__ **** #初始化# 单例模式 —— 设计模式# 一个类 从头到尾 只创建 一个对象# class Singleton:# def __new__(cls, *args):# if not hasattr(cls, '_instance'):# cls._instance = object.__new__(cls)# return cls._instance## def __init__(self,name):# self.name = name## one = Singleton('alex')# print(one.name)# two = one# two.name = 'egon'# # two = Singleton('egon')# # print(two.name)# # print(one.name)# print(id(one),id(two))# class Foo:# def __init__(self):# pass## def __call__(self, *args, **kwargs):# print('__call__')## Foo()() #对象名()# class A:# def __eq__(self,obj): #equal : 相等# # if self.a == obj.a and self.b == obj.b:# return True# a = A()# b = A()# a.name = 'alex'# b.name = 'egon'# print(a == b)# from collections import namedtuple# Card = namedtuple('Card',['rank','suit'])# class FranchDeck:# ranks = [str(n) for n 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## deck = FranchDeck()# # print(deck._cards)# print(deck[0])# # from random import choice# # print(choice(deck))# # print(choice(deck))# from random import shuffle# shuffle(deck)# print(deck._cards)# 一个类 有 100个 对象,每一个对象都拥有三个属性:name,sex,age# 如果两个对象的name和sex属性完全一致# 我就认为这是一个对象# 请对这100个对象进行去重# class Person:# def __init__(self,name,age,sex):# self.name = name# self.age = age# self.sex = sex# def __hash__(self):# return hash(self.name+self.sex)# def __eq__(self, other):# if self.name == other.name and self.sex == other.sex:return True## p_lst = []# for i in range(84):# p_lst.append(Person('egon',i,'male'))# print(set(p_lst))
下面这一版的内置方法是添加了更多的更详尽注释的:
# str 和 repr# class A:# # pass# def __str__(self):# return 'A的对象' # def __repr__(self): # return 'repr: A的对象'# a = A()# print(a) # 本质调用的是__str__,如果没实现,就调用__repr__, 再找不到,用object父类的# print(a.__str__()) # str却不能给repr做备胎# print(a.__repr__()) # repr是str的备胎# 打印一个对象的时候,实际上是调用了这个对象所在类的__str__方法,打印的是这个方法的返回值# print(str(a))# print(repr(a))# print('%s'%a)# print('%r'%a)# print(a)# l = list()# print(l)# format_dict={ # 'nat':'{o.name}-{o.addr}-{o.type}',#学校名-学校地址-学校类型# 'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址# 'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名# }# class School:# def __init__(self,name,addr,type):# self.name=name# self.addr=addr# self.type=type## def __format__(self, format_spec): #format_spec = 'nat'# fmt='''=====================# 姓名 : {obj.name}# 班级 : {obj.addr}# ====================='''# return fmt.format(obj=self)# s1=School('oldboy1','北京','私立')# print(format(s1,'nat'))# print(format(s1,'tna'))# print(format(s1,'tan'))# print(format(s1,'asfdasdffd'))# 打印学生信息# 姓名 班级 性别 年龄# =====================# 姓名 : name# 班级 : class# =====================# 析构方法# 周期 :0# 12 一个亿的对象 del 对象# class A:# def __del__(self):# '''# 析构方法# 这个方法只有在执行del A类的对象的时候才被触发# 且先执行代码中的内容,再删除对象# 如果我删除了这个对象,它跟着还有一些其他的附属的内容也没有用了# 我们就可以在这个方法中回收掉# '''# print('执行我啦!')# self.b.close() ## 这里self就是a,self是实例化的对象,所以a.b就是self.b# 所以这里也解释了为什么这里的b要和下面a后面的b保持一致的原因# f = open('file','w')# a = A()# a.b = f ## 这里是添加一个属性,a是A实例化出来的一个对象,a.b = f 这是把对象所添加的属性赋值给f# del a# print(a)class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): if item == 1: print('hahaha') # print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key] = value def __delitem__(self, key): print('del obj[key]时,我执行') self.__dict__.pop(key) def __delattr__(self, item): print('del obj.key时,我执行') self.__dict__.pop(item)f1 = Foo('sb')# 访问属性的方式变了# 对象名.属性# f1=Foo('sb')# f1['age']=18 #给f1添加一个属性# del f1['age'] #删除属性# # f1.name# print(f1['name'])## f1.__dict__['age'] = 18# f1['age1']=19# del f1.age1 #删除属性## f1['name']='alex'# print(f1.__dict__)#pytho内部的约定#关于item : 对象访问 如果是 对象名[],是因为内部实现了item系列的方法# 对象的实例化 # 创造一个裸地对象 —— __new__ **** # 初始化# 单例模式 —— 设计模式# 一个类 从头到尾 只创建 一个对象# class Singleton:# def __new__(cls, *args):# if not hasattr(cls, '_instance'):# cls._instance = object.__new__(cls)# return cls._instance## def __init__(self,name):# self.name = name## one = Singleton('alex')# print(one.name)# two = one# two.name = 'egon'# # two = Singleton('egon')# # print(two.name)# # print(one.name)# print(id(one),id(two))# class Foo:# def __init__(self):# pass## def __call__(self, *args, **kwargs):# print('__call__')## Foo()() #对象名()# class A:# def __eq__(self,obj): #equal : 相等# # if self.a == obj.a and self.b == obj.b:# return True# a = A()# b = A()# a.name = 'alex'# b.name = 'egon'# print(a == b)# from collections import namedtuple# Card = namedtuple('Card',['rank','suit'])# class FranchDeck:# ranks = [str(n) for n 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## deck = FranchDeck()# print(deck._cards)# print(deck[0])# # from random import choice# # print(choice(deck))# # print(choice(deck))# from random import shuffle# shuffle(deck)# print(deck._cards)# 一个类 有 100个 对象,每一个对象都拥有三个属性:name,sex,age# 如果两个对象的name和sex属性完全一致# 我就认为这是一个对象# 请对这100个对象进行去重class Person: def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def __hash__(self): # 这里使用hash方法把字符串拼接起来,得到一个新的字符串, # 如果得到的新的字符串都相同那么这两个元素就是想等的,不仅仅是字符串可以用hash,hash是不可变的数据类型, # (可hash不可变数据类型) return hash(self.name+self.sex) def __eq__(self, other): # 我们去重需要使用集合,因为集合的最大特点就是去重,那么集合里面不仅仅是包含了不可变 # 数据类型,还有可变数据类型,当我们遇到可变数据类型的时候那么我们就需要使用eq去判断他们的值是否相等了, # 这样使得程序更加趋于完善,可以hold住更多的可能 if self.name == other.name and self.sex == other.sex:return Truep_lst = []for i in range(84): p_lst.append(Person('egon', i, 'male'))print(set(p_lst))# 一句话总结就是可hash属于不可变的数据类型,需要使用hash去判断是否相等,# 那么不可hash可变的数据类型呢,就不能够使用hash去判断了,需要使用eq去判断是否相等