派生方法的实战
1.什么是派生方法(通俗概述):
派生方法通俗讲就是当运行模块函数时可以在途中进行拦截然后添加自己需要添加的操作然后再返回继续执行原本的模块函数。
2.代码实战:
拓展支持json序列话的数据类型:
+-------------------+---------------+ | Python | JSON | +===================+===============+ | dict | object | +-------------------+---------------+ | list, tuple | array | +-------------------+---------------+ | str | string | +-------------------+---------------+ | int, float | number | +-------------------+---------------+ | True | true | +-------------------+---------------+ | False | false | +-------------------+---------------+ | None | null | +-------------------+---------------+ '''ps:要进行序列化的数据必须全部都是上述类型才可以'''
当用json模块序列化字典内有json不支持序列类型的数据时会报错
import json import datetime d = { 't1': datetime.datetime.today(), 't2': datetime.date.today() } res = json.dumps(d) # 因为字典值是日期型所以不能被序列化 print(res)
这时可以通过派生方式拦截dumps内置函数把数据进行转换再进行序列话
import datetime import json d = { 't1': datetime.datetime.today(), 't2': datetime.date.today()} '''通过查看dumps源码进行改动''' class MyJsonEncode(json.JSONEncoder): def default(self, data): '''data就是json即将要序列化的数据''' if isinstance(data, datetime.datetime): return data.strftime('%Y-%m-%d %H:%M:%S') elif isinstance(data, datetime.date): return data.strftime('%Y-%m-%d') '''如果是可以序列化的类型 那么不做任何处理 直接让它序列化即可''' return super().default(data) res = json.dumps(d, cls=MyJsonEncode) print(res) json.dumps(d, cls=MyJsonEncode)
面向对象三大特性之封装
1.封装的简介
封装其实就是指隐藏对象的数据和功能,隐藏的数据开设特定的接口用户需要使用接口才可以使用,能够提高程序安全性。
2.隐藏属性
在类定义阶段使用双下划线开头的名字都是隐藏的属性
隐藏的数据不是让用户无法使用 只不过需要做变形的处理
(用改变后的名字去访问隐藏数据就失去了隐藏的意义)
__变量名 __类名__变量名
class A: def __name(self): print('from A') def test(self): self.__name() class B(A): def __name(self): print('from B') obj=B() obj.test() '''打印结果 from A '''
3.property伪装属性
property可以简单的理解为把方法伪装成数据
eg:将方法obj.func()伪装成数据 obj.func 关键字(@property)
class Person: def __init__(self,chinese,mathematics,English): self.chinese = chinese self.mathematics = mathematics self.english = English @property def average_value(self): return (self.chinese+self.mathematics+self.english)/3 obj = Person(88,90,59) print(obj.average_value) # 不需要写括号 '''打印结果 79.0 '''
面向对象三大特性之多态
1.什么是多态有什么作用
一种事物的多种不同形态,比如衣服它可以是长袖、短袖、衬衫、卫衣等等不同的形态但都有衣服的固定功能。所以当代码中有公共的功能时我们可以定义成一个固定的功能无论哪个要用直接调用即可。
2.代码实现
class Clothes(object) def ornament(self): pass class Short_sleeves(Clothes) def ornament(self): print('今天穿短袖') class Sweatshirt(Clothes) def ornament(self): print('今天穿卫衣') class Dress(Clothes) def ornament(self): print('今天穿裙子') s1 = Short_sleeves() s2 = Sweatshirt() s3 = Dress() s1.ornament() '''今天穿短袖''' s2.ornament() '''今天穿卫衣''' s3.ornament() '''今天穿裙子'''
3.知识拓展
""" python也提供了一种强制性的操作(了解即可) 应该是自觉遵守 """ import abc # 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化 class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod # 该装饰器限制子类必须定义有一个名为talk的方法 def talk(self): # 抽象方法中无需实现具体的功能 pass class Person(Animal): # 但凡继承Animal的子类都必须遵循Animal规定的标准 def talk(self): pass def run(self): pass obj = Person()
ps:在python中一切皆对象!!!
面向对象之反射
1.什么是反射有什么作用
可以用字符串的方式操作对象的数据或方法,例如用户想判断对象中是否有某个变量名时因为input获取的是字符串所以可以用反射来处理。当看到需求中有字符串和对象时可以肯定需要用反射来操作。
2.反射的四个主要方法
hasattr():判断一个对象中是否有某个字符串对应的属性
getattr():获取对象字符串对应的属性 一般 hasattr 和 getattr 结合使用
setattr():根据字符串给对象设置属性
delattr():根据字符串给对象删除属性
3.代码展示
将hasattr与getattr相结合使用先判断是否存在再获取存在对应的属性
class Person: type = '是个人' def profile(self): print('小胖子') obj = Person() while True: target_name = input('请输入你要查找的名字>>>:').strip() if hasattr(obj, target_name): print(getattr(obj, target_name)) else: print('对不起,没找到你要的对象') '''打印结果 请输入你要查找的名字>>>:type 是个人 请输入你要查找的名字>>>:profile <bound method Person.profile of <__main__.Person object at 0x7fba284c6fd0>> '''
class Person: type = '是个人' def profile(self): print('小胖子') obj = Person() setattr(obj,'name','aa') # 对象没有这个属性则添加属性 setattr(obj,'age',18) # 对象没有这个属性则添加属性 print(obj.age) delattr(obj,'name') # 删除对象内的属性 print(obj.__dict__) '''打印结果 18 {'age': 18} '''