#程序可以访问检测修改它本身状态的能力。
# 四个函数 参数均是 前面func名称,后面是字符串
# hasattr() object,name 判断object中有没有一个name字符串对应的方法或者属性
# getattr() 获得func的属性字典(__dict__)中key对应的值,数据属性就是值,函数属性就是地址。= func.name
# setattr() 设置,和改字典一样。
# delattr() =del class.fun
#eg:
#class awm():
# def __init__(self,name):
# self.name = name
# pass
# def one_shot(self):
# pass
#
# ga = hasattr(awm, 'one_shot') #函数有return返回值
# print(ga) #打印返回值 True
# ga2 = hasattr(awm,'name') #False
# print(ga2)
#
#
# a1 = awm('good')
# g3 = hasattr(a1, 'name') #从b1属性字典中找__name__ b1.__dic_['name]
# print(g3) #实例的name参数传入,name有。
#为什么用反射?比如可插阀设计。
# class FtpClient():
# def __init__(self,addr):
# print("正在访问客户端 %s" %addr)
# self.addr = addr
# pass
#
# def put(self):
# print("正在上传")
#
# from ftp_client import FtpClient
#
# f1= FtpClient("1.1.1.1")
# print(f1)
#
# if hasattr(f1,"put"): #如果f1有put函数
# func_get = getattr(f1,"put") #得到函数内存地址
# func_get() #运行该地址的函数
# else: #如果f1没有put函数
# print("next") #执行下一个函数
#这样,没做完的函数没影响其他人进度。
#反射事先定义好借口,接口只有在被完成后才能真正运行。
#动态导入模块
#一般的是 import numpy
#如果是需要导入一个字符串,__import__("str")可以自动把字符串换成模块名
# __import__("numpy") 返回的是最顶层的模块。
# __import__("numpy.pyplot") 实际上拿到的是numpy,不是pyplot
#import importlib
#import importlib.import_module("numpy.pyplot") #字符串
#这样就可以拿到你想要找到的模块
#类的内置属性 __setattr__,__delattr__,__getattr__
#只有在属性不存在时,自动触发__getattr__
#del f1.x 在删除x属性时会触发
#f1.y = 10 设置属性的时候会触发setattr
#怎么用呢
# class Foo(): #这些内置函数操作的本质都是操作__dic__的底层属性字典。
# def __init__(self,name):
# self.name = name
#
# def __getattr__(self,item): #def __getattr__(self,item)
# print("找不到这个方法")
# def __setattr__(self, key, value): #定制设置属性
# self.__dict__[key] = value
# print("执行这个方法",key,value)
# def __delattr__(self, item):
# print("执行删除", item)
# self.__dict__pop(item)
# f1 = Foo("yishu")
# f1.age =18
# #print(f1.age)
#二次加工标准类型
#产生标准类型都有基本的两种方式
# x = 'sdfdsf' x = str() str工厂函数,其实str就是一个类,这个句子就是实例化的过程。
#相同的,还有 list,tuple等。
#那么,作为类,就有封装,多态继承的三个特性。
# class List(list):
# pass
# l1 = List("hello") #实例化
#相当于
# l2 = list("hello")
#那么,List这个派生的类把list这个类继承过来了。
#如果说我想写一个list显示中间字符的类,怎么写?
#为了不写重复代码,再想一下,list其实本质是一个类,一个对象。
#那么,新的class可以继承list的特性。
# class List(list):
# def show_middle(self):
# middle_index = int(len(self)/2)
# return self[middle_index]
#
# l1 = List("hello")
# print(l1.show_middle()) #输出 l
# class List(list):
# def append(self, object):
# pass
# def show_middle(self):
# middle_index = int(len(self)/2)
# return self[middle_index]
#
# l1 = List("hello")
# # print(l1.show_middle())
# l1.append(3)
# print(l1) #['h', 'e', 'l', 'l', 'o'] 没有把3传进去,说明新加的append把父类的append覆盖住,首先先检索自己的方法,如果没有才往上找。
#如果想先判断传入的如果是字符串,就append呢?
# class List(list):
# def append(self, object):
# if type(object) is str: #判断传入字符是否为字符串
# super().append (object) #这里用super调取夫类的append方法,不用传自己
# else:
# print("只能传入字符串")
# def show_middle(self):
# middle_index = int(len(self)/2)
# return self[middle_index]
#
# l1 = List("hello")
# l1.append(111)
# print(l1)
#还可以这样,用if not isinstance()
class List(list):
def append(self, item):
if not isinstance(item, int):
raise TypeError ('your input is not a int')
super().append(item)
a = List()
a.append('fsd')
print(a)
##############
class TypedList(list):
def __init__(self, type):
self.type = type
def append(self, item):
if not isinstance(item, self.type):
raise TypeError(item is not of type %s' % self.type)
super(TypedList, self).append(item) #append the item to itself (the list)
#以上就是通过继承和派生的概念来包装基本数据类型,定制自己的数据类型。
getattr,setattr,defattr,__getattr__,__setattr__,__delattr__,反射,继承,派生
最新推荐文章于 2021-09-27 12:51:01 发布