萨达萨达是
作者:互联网
- 派生方法的实战(非非菲菲菲菲常重要)
- 什么是派生
- 派生方法的使用
- 面向对象三大特征之封装
- 封装是什么
- 封装的实现
- property伪装属性
1.派生方法的实战(非非菲菲菲菲常重要)
在学派生实战之前我们再来回顾一下什么是派生
1.1什么是派生:
指的是子类继承父类的属性方法,并且派生出自己独有的属性与方法
通过super来指向父类的属性(super()是一个特殊的类,调用super得到一个对象,该对象指向父类的名称空间)
ok,下面我们来看一串代码:
d = {
't1': datetime.datetime.today(),
't2': datetime.date.today()
}
res = json.dumps(d)
print(res)
我的目的是想将这个字典用json的方式序列化,但是执行后发现不可行,会报错:
raise TypeError(f'Object of type {o.__class__.__name__} ' TypeError: Object of type datetime is not JSON serializable |
所以这个时候我们来查看一下报错的源码(json.JSONEncoder):
在报错的源码中有一个关于default的描述:
class JSONEncoder(object):
"""Extensible JSON <http://json.org> encoder for Python data structures.
Supports the following objects and types by default:
+-------------------+---------------+
| Python | JSON |
+===================+===============+
| dict | object |
+-------------------+---------------+
| list, tuple | array |
+-------------------+---------------+
| str | string |
+-------------------+---------------+
| int, float | number |
+-------------------+---------------+
| True | true |
+-------------------+---------------+
| False | false |
+-------------------+---------------+
| None | null |
+-------------------+---------------+ # 就是说即将要被序列化的数据要在这些数据类型中,其他的乱七八糟的就会报错
可以看出我们datetime模块得出的字符不属于左边这一列的数据类型,同样的json也无法接受,那咋整?这个时候我们就要用到我们的派生方法(你可看好楼)
2 派生方法的使用
我们新建一个MyJsonEncode类,然后将json.JSONEncoder作为他的父类,然后继承他,然后对内部的default进行重新定义(错误就是出现在这里的嘛),用isinstance内置函数进行判断我们输入的数据类型即可!
派生方法序列化代码
d = {
't1': datetime.datetime.today(),
't2': datetime.date.today()
}
# res = json.dumps(d)
"""
class JSONEncoder:
pass
dumps(obj,cls=None):
if cls == None:
cls = JSONEncoder
return cls(...) # JSONEncoder()
查看JSONEncoder源码发现序列化报错是有default方法触发的
raise TypeError(f'Object of type {o.__class__.__name__} '
f'is not JSON serializable')
我们如果想要避免报错 那么肯定需要对default方法做修改(派生)
"""
class MyJsonEncode(json.JSONEncoder):
def default(self, o):
'''o就是json即将要序列化的数据'''
if isinstance(o, datetime.datetime):
return o.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(o, datetime.date):
return o.strftime('%Y-%m-%d')
# 如果是可以序列化的类型 那么不做任何处理 直接让它序列化即可
return super().default(o)
res = json.dumps(d, cls=MyJsonEncode)
print(res)
json.dumps(d, cls=MyJsonEncode)
isinstance()是Python中的一个内建函数。是用来判断一个对象的变量类型
strftime()函数可以把YYYY-MM-DD HH:MM:SS格式的日期字符串转换成其它形式的字符串
2.面向对象三大特征之封装
1.封装是什么
封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。 2.如何操作1.在类定义阶段使用双下划线开头的名字 都是隐藏的属性 后续类和对象都无法直接获取 2.在python中不会真正的限制任何代码 隐藏的属性如果真的需要访问 也可以 只不过需要做变形处理 __变量名 _类名__变量名 ps:既然隐藏了 就不改使用变形之后的名字去访问 这样就失去了隐藏的意义 |
封装的代码
class Student(object):
__school = '清华大学'
def __init__(self, name, age):
self.__name = name
self.__age = age
# 专门开设一个访问学生数据的通道(接口)
def check_info(self):
print("""
学生姓名:%s
学生年龄:%s
""" % (self.__name, self.__age))
# 专门开设一个修改学生数据的通道(接口)
def set_info(self,name,age):
if len(name) == 0:
print('用户名不能为空')
return
if not isinstance(age,int):
print('年龄必须是数字')
return
self.__name = name
self.__age = age
stu1 = Student('jason', 18)
stu1.set_info('','我很大')
"""
我们编写python很多时候都是大家墨守成规的东西 不需要真正的限制
class A:
_school = '清华大学'
def _choice_course(self):
pass
"""
3.property伪装属性
可以简单的理解为 将方法伪装成数据
标签:封装,name,self,datetime,json,萨达萨达,+-------------------+---------------+ 来源: https://www.cnblogs.com/scx-xiaochun/p/16529282.html