CodeYarn青鸟川中青鸟

多态 反射

Toretto·2022-11-07 21:20·25 次阅读

多态 反射

今日内容

派生方法实战演练#

Copy
import json import datetime d= { 't1':datetime.datetime.today(), 't2':datetime.date.today(), 't3':'我是字符串' } res = json.dumps(d) print(res) ''' 序列化报错 raise TypeError(f'Object of type {o.__class__.__name__} ' 引发TypeError(f'对象类型{o.__class__.)__name__} ' TypeError: Object of type datetime is not JSON serializable datetime类型的对象不是JSON可序列化的 ''' ''' 能够被序列化的数据是有限的>>>:里里外外必须都是下列左边的类型 +-------------------+---------------+ | Python | JSON | +===================+===============+ | dict | object | +-------------------+---------------+ | list, tuple | array | +-------------------+---------------+ | str | string | +-------------------+---------------+ | int, float | number | +-------------------+---------------+ | True | true | +-------------------+---------------+ | False | false | +-------------------+---------------+ | None | null | +-------------------+---------------+ '''

转换方式1:手动转类型(简单粗暴)#

Copy
d= { 't1':str(datetime.datetime.today()), 't2':str(datetime.date.today()), } #直接在要转换的前面加上str 变成字符串 res = json.dumps(d) print(res) #{"t1": "2022-11-07 14:59:53.367927", "t2": "2022-11-07"}

转换方式2:派生方法(儒雅高端)#

Copy
''' 查看dumps源码 注意cls参数 默认传JsonEncoder 查看该类的源码 发现default方法是报错得到发起者 编写类继承JsonEncoder并重写default方法 之后调用dumps手动传cls = 我们自己写的类 ''' res = json.dumps(d) class MyJsonEconder(json.JSONEncoder): #继承父类 json.JSONEncoder def default(self, o) : #使用default功能 """ :param o:接收无法被序列化的数据 :return: 返回可以被序列化的数据 """ if isinstance(o,datetime.datetime): #判断是否是datetime类型 如果是则处理成可以被序列化的类型 return o.strftime('%Y-%m-%d %X') elif isinstance(o,datetime.date): return o.strftime('%Y-%m-%d') return super().default(o) #最后还是调用原来的方法 防止有一些额外操作没有做 res= json.dumps(d,cls=MyJsonEconder) print(res) # {"t1": "2022-11-07 15:47:32.217589", "t2": "2022-11-07"}

面向对象三大特征之封装#

Copy
封装:就是将数据和功能"封装"起来 隐藏:将数据和功能隐藏起来不让用户直接调用 而是开发一些接口简介调用 从而可以在接口内添加额外的操作 伪装:将类里面的方法伪装成类里面的数据 class c: def func(self): pass obj = c() obj.func() '''经过伪装''' obj.func 封装: class MyClass(): school_name = '学校名' _ = '哈哈哈哈' _name = '哈哈哈哈1' def __choice_course(self): print('正在选课') ''' 类在定义阶段 名字前面有两个下划线 那么改名字就会被隐藏起来 无法直接访问 ''' __age = 18 ''' 在python中其实没有真正意义上的隐藏 仅仅是换了个名字而已 __age 换成了 _MyClass__age ''' print(MyClass.school_name) #学校名 obj = MyClass() print(obj.school_name) #学校名 print(obj._) #哈哈哈哈 print(MyClass._) #哈哈哈哈 print(obj._name) #哈哈哈哈1 print(MyClass._name) #哈哈哈哈1 #无法隐藏 MyClass.__age = 'ccc' print(MyClass.__age) #ccc 无法隐藏 obj = MyClass() obj.__addr = '派出所' print(obj.__addr) print(MyClass.__dict__) # 查看类的名称空间中的名字 找到隐藏的__age的名字 是_MyClass__age print(MyClass._MyClass__age) #可以通过调这个名字来获取值 不能用 失去隐藏的含义了 ''' 隐藏 只有在定义阶段才生效 后面无法隐藏 隐藏以后要通过别的方式才能使用''' class Person: def __init__(self,name,age,hobby): self.__name = name self.__age = age self.__hobby = hobby #对象也可以拥有隐藏属性 def get_info(self): #类体代码中 可以直接使用名字(只有定义的时候不能用 只能定义隐藏的东西) print(f""" 姓名:{self.__name} 年龄:{self.__age} 爱好:{self.__hobby} """) #隐藏的属性 开放修改的接口 可以定义很多功能 def set_name(self,new_name): if len(new_name) == 0: raise ValueError('好歹写点东西') if new_name.isdigit(): raise ValueError('名字不能是数字') self.__name = new_name obj = Person('jason',18,'music') #类 定义了一个对象 将所需参数上传 obj.get_info() #调用封装隐藏函数的接口 obj.set_name('abc老师') #定义一个可以修改隐藏功能的接口函数 #修改封装函数中的name 直接修改 obj.get_info() #调用隐藏功能所在函数 obj.set_name('') #可以在修改接口中 定义一些条件 比如民改造不能是数字、不能为空 ''' 以后我们在编写面向对象代码类的定义时 也会看到很多但下划线开头的名字 表达的意思通常特使不要直接访问 卫视查找一下 下面可能定义的接口 单下划线 双下划线都是表示隐藏文件 '''

伪装#

Copy
BMI指数: 衡量一个人的体重与身高对健康影响的一个指标 体质指数(BMI) = 体重(kg)÷身高*身高(m) class Person(object): def __init__(self,name,height,weight): self.name = name self.height = height self.weight = weight @property def BMI(self): return self.weight/(self.height**2) p1 = Person('jason', 1.7, 78) # p1.BMI() # BMI应该作为人的基本数据而不是方法 print(p1.BMI) # 利用装饰器伪装成数据 class Foo: def __init__(self,val): self.__NAME = val @property def name(self): return self.__NAME @name.setter def name(self,value): if not isinstance(value,str): #在设定值之前进行类型检查 raise Exception('%s must be str' % value) self.__NAME = value #通过类型检查后 将值value存放到真实的位置self.__NAME @name.deleter def name(self): raise PermissionError('can not delete') f = Foo('lili') print(f.name) #lili f.name = 'lili666' print(f.name) del f.name f.name = 'jason' # 触发name.setter装饰器对应的函数name(f,’jason') f.name = 123 # 触发name.setter对应的的函数name(f,123),抛出异常TypeError del f.name # 触发name.deleter对应的函数name(f),抛出异常PermissionError

三大特性之多态#

Copy
多态: 一种事物的多种形态 水:固态、液态、气态 动物:猫、狗、猪 class Animal: def spark(self): #叫的方法 pass class Cat(Animal): # def miao(self): # print('喵喵') def spark(self): print('喵喵') class Dog(Animal): # def wang(self): # print('汪汪') def spark(self): print('汪汪') class Pig(Animal): # def heng(self): # print('哼哼') def spark(self): print('哼哼') ''' 面向对象中多态意思是 一种食物可以有多种形态 但是针对相同功能应该定义相同的方法 这样无论我们拿到的是那个具体的事物 都可以通过相同的方法调用功能 ''' s1 = 'hello word' l1 = [11,22,33,44] d1 = {'name':'jason','password':123123123} print(len(s1)) #10 print(len(l1)) #4 print(len(d1)) #2 ''' 鸭子类型:只要你看上去像鸭子 走路像鸭子 说话像鸭子 那么你就是鸭子 ''' """ 文件 能够读取数据也能够保存数据 内存 能够读取数据也能够保存数据 硬盘 能够读取数据也能够保存数据 一切皆文件 因为都可以读和取 """ class File: def read(self): pass def write(self): pass class Memory: def read(self): pass def write(self): pass class Disk: def read(self): pass def write(self): pass """ python永远体长自由简介大方 不约束程序员的行为 但是多态提供了约束的方法 """ import abc class Animal(metaclass=abc.ABCMeta): #指定metacclass属性将类设置为抽象类 抽象类本身只是用来约束子类的 不能被实例化 @abc.abstractmethod #该装饰器限制子类必须定义有一个名为talk的方法 def talk(self): pass #抽象方法中无需实现具体功能 class Cat(Animal): #但凡继承Animal的子类必须遵循Animal规定的标准 def talk(self): pass cat = Cat() #若子类中没有一个名为talk的方法则会抛出异常TypeError,无法实例化

没面向对象之反射#

Copy
利用字符串操作对象的数据和方法: 1.hasattr() 重点 判断对象是否含有某个字符串对应的属性名或方法名 2.getattr 根据字符串获取对象对应的属性名(值)或方法名(函数体代码) 3.setattr 根据字符串给对象设置或者修改数据 4.delattr 根据字符串删除对象里面的名字 # class C1: # school_name = '小姐姐学院' # # def choice_course(self): # print('大宝贝们正在选课') # # obj = C1() '''判断某个名字对象是否可以使用(存在)''' # 推导思路 # try: # obj.xxx # except AttributeError: # print('你木有这个名字') '''判断用户随意指定的名字对象是否可以使用(存在)''' # target_name = input('请输入对象可能使用的名字>>>:').strip() # try: # obj.target_name # except AttributeError: # print('你木有这个名字') """ 字符串的名字跟变量名区别大不大 'school_name' school_name 非常大 完全不一样 """ # 反射:利用字符串操作对象的数据和方法 # print(hasattr(obj, 'school_name')) # True # print(getattr(obj, 'school_name')) # 小姐姐学院 # print(getattr(obj, 'choice_course')) # <bound method C1.choice_course of <__main__.C1 object at 0x00000248C0B65A30>> class C1: school_name = '小姐姐学院' def choice_course(self): print('大宝贝们正在选课') obj = C1() while True: target_name = input('请输入您想要操作的名字>>>:') if hasattr(obj, target_name): print('恭喜您 系统中有该名字') # 获取该名字对应的数据(值 函数) data_or_func = getattr(obj, target_name) if callable(data_or_func): print('您本次使用的是系统中的某个方法') data_or_func() else: print('您本次使用的是系统中的某个数据') print(data_or_func) else: print('很抱歉 系统中没有该名字')

反射实战案例#

Copy
1.什么时候应该考虑使用反射 只要需求中出现了关键字 对象....字符串.... 2.实战案例 1.模拟cmd终端 class WinCmd: def tasklist(self): print(""" 1.学习编程 2.学习python 3.学习英语 """) def ipconfig(self): print(""" 地址:127.0.0.1 地址:上海浦东新区 """) def get(self, target_file): print('获取指定文件',target_file) def put(self, target_file): print('上传指定文件',target_file) def server_run(self): print('欢迎进入简易版本cmd终端') while True: target_cmd = input('请输入您的指令>>>:') res = target_cmd.split(' ') if len(res) == 1: if hasattr(self, res[0]): getattr(self, res[0])() else: print(f'{res[0]}不是内部或者外部命令') elif len(res) == 2: if hasattr(self, res[0]): getattr(self, res[0])(res[1]) else: print(f'{res[0]}不是内部或者外部命令') obj = WinCmd() obj.server_run() 2.一切皆对象 # 利用反射保留某个py文件中所有的大写变量名及对应的数据值 import settings print(dir(settings)) # dir列举对象可以使用的名字 useful_dict = {} for name in dir(settings): if name.isupper(): useful_dict[name] = getattr(settings, name) print(useful_dict) # while True: # target_name = input('请输入某个名字') # if hasattr(settings, target_name): # print(getattr(settings, target_name)) # else: # print('该模块文件中没有该名字')
posted @   李李大冒险  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
  1. 1 不可撤销
  2. 2 小年兽 程嘉敏
  3. 3 迷人的危险3 FAFA
  4. 4 山楂树之恋 程佳佳
  5. 5 summertime cinnamons / evening cinema
  6. 6 不谓侠(Cover 萧忆情Alex) CRITTY
  7. 7 神武醉相思(翻自 优我女团) 双笙(陈元汐)
  8. 8 空山新雨后 音阙诗听 / 锦零
  9. 9 Wonderful U (Demo Version) AGA
  10. 10 广寒宫 丸子呦
  11. 11 陪我看日出 回音哥
  12. 12 春夏秋冬的你 王宇良
  13. 13 世界が终わるまでは… WANDS
  14. 14 多想在平庸的生活拥抱你 隔壁老樊
  15. 15 千禧 徐秉龙
  16. 16 我的一个道姑朋友 双笙(陈元汐)
  17. 17 大鱼 (Cover 周深) 双笙(陈元汐)
  18. 18 霜雪千年(Cover 洛天依 / 乐正绫) 双笙(陈元汐) / 封茗囧菌
  19. 19 云烟成雨(翻自 房东的猫) 周玥
  20. 20 情深深雨濛濛 杨胖雨
  21. 21 Five Hundred Miles Justin Timberlake / Carey Mulligan / Stark Sands
  22. 22 斑马斑马 房东的猫
  23. 23 See You Again Wiz Khalifa / Charlie Puth
  24. 24 Faded Alan Walker
  25. 25 Natural J.Fla
  26. 26 New Soul Vox Angeli
  27. 27 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  28. 28 像鱼 王贰浪
  29. 29 Bye Bye Bye Lovestoned
  30. 30 Blame You 眠 / Lopu$
  31. 31 Believer J.Fla
  32. 32 书信 戴羽彤
  33. 33 柴 鱼 の c a l l i n g【已售】 幸子小姐拜托了
  34. 34 夜空中最亮的星(翻自 逃跑计划) 戴羽彤
  35. 35 慢慢喜欢你 LIve版 戴羽彤
  36. 36 病变 戴羽彤
  37. 37 那女孩对我说 (完整版) Uu
  38. 38 绿色 陈雪凝
  39. 39 月牙湾 LIve版 戴羽彤
像鱼 - 王贰浪
00:00 / 04:45
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 周有才

作曲 : 周有才

这是一首简单的歌

没有什么独特

试着代入我的心事

它那么幼稚

像个顽皮的孩子

多么可笑的心事

只剩我还在坚持

谁能看透我的眼睛

让我能够不再失明

我要记住你的样子

像鱼记住水的拥抱

像云在天空中停靠

夜晚的来到

也不会忘了阳光的温暖

我要忘了你的样子

像鱼忘了海的味道

放下所有梦和烦恼

却放不下回忆的乞讨

多么可笑的心事

只剩我还在坚持

谁能看透我的眼睛

让我能够不再失明

记住你的样子

像鱼记住水的拥抱

像云在天空中停靠

夜晚的来到

也不会忘了阳光的温暖

我要忘了你的样子

像鱼忘了海的味道

放下所有梦和烦恼

却放不下回忆的乞讨

只剩自己就好

点击右上角即可分享
微信分享提示
目录