其他分享
首页 > 其他分享> > 萨达萨达是

萨达萨达是

作者:互联网

  1. 派生方法的实战(非非菲菲菲菲常重要)
    1. 什么是派生
    2. 派生方法的使用
  2. 面向对象三大特征之封装
    1. 封装是什么
    2. 封装的实现
  3. 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