getattr,setattr,defattr,__getattr__,__setattr__,__delattr__,反射,继承,派生

#程序可以访问检测修改它本身状态的能力。
# 四个函数 参数均是 前面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)


#以上就是通过继承和派生的概念来包装基本数据类型,定制自己的数据类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值