继承json模块并派生、组合、封装与访问限制

一、继承json模块并派生新的功能

继承json模块中JSONEncoder,并派生出新的功能。

import json
from datetime import date, datetime


# 在原来json模块中可序列化的数据类型优先
# <class 'datetime.datetime'>  date
# print(type(datetime.now()))
#
# dict1 = {
#     # 'time1': str(datetime.now())
#     'time1': datetime.now()
# }
#
# res = json.dumps(dict1)
# print(res)  # 'd
class MyJson(json.JSONEncoder):
    # datetime.now() ---> o
    def default(self, o):
        # isinstance: 判断一个对象是否是一个类的实例
        if isinstance(o, datetime):  # True
            return datetime.strftime(o, '%Y-%m-%d %X')

        else:
            return super().default(self, o)

dict1 = {
    # 'time1': str(datetime.now())
    'time1': datetime.now(),
    'name': 'tank'
}

# 指定自定义的一个MyJson  派生类
# cls=自定义的类
res = json.dumps(dict1, cls=MyJson)
print(res)

 

二、组合

1、什么是组合?

组合是一个对象中,包含另一个或多个对象。

2、为什么使用组合?

减少代码的冗余。

3、使用方法:

class People:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

class Teacher(People):
    def __init__(self, name, age, sex):
        super().__init__(name, age, sex)


class Student(People):
    def __init__(self, name, age, sex):
        super().__init__(name, age, sex)

class Date:
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def tell_birth(self):
        print(f'''
        ====出生日期====
        年:{self.year}
        月:{self.month}
        日:{self.day}
        ''')


s1 = Student('aa', 18, 'male')
date_obj = Date(2019, 6, 6)

#给学生对象添加一个自定义日期对象
s1.date_obj = date_obj


s1.date_obj.tell_birth()

练习:

'''
练习需求:
    选课系统:
        1.有学生、老师类,学生与老师有属性 “名字、年龄、性别、课程”,
        2.有方法 老师与学生可以添加课程, 打印学习/教授课程。

    # 组合实现
'''


class People:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    # 打印出生日期方法
    def tell_birth(self):
        print(f'''
        年: {self.date_obj.year}
        月: {self.date_obj.month}
        日: {self.date_obj.day}
        ''')

    # 添加课程
    def add_course(self, course_obj):
        # self.course_name = course_name
        # self.course_price = course_price
        # self.course_time = course_time
        self.course_list.append(course_obj)

    # 打印当前对象中课程列表的所有课程信息
    # ---》 打印所有课程
    def tell_all_course_info(self):
        # 从当前对象中课程列表中取出所有的课程对象
        for course_obj in self.course_list:
            # 通过课程对象.打印课程信息方法
            course_obj.tell_course_info()


class Student(People):
    # 假设从程序开始到灭亡  在实例化时都不修改该对象的属性
    def __init__(self, name, age, sex):
        super().__init__(name, age, sex)
        self.course_list = []


class Teacher(People):
    def __init__(self, name, age, sex):
        super().__init__(name, age, sex)
        self.course_list = []


class Date:
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day


# 定义一个课程类: 课程有: 课程名称, 课程价格, 课程周期
class Course:
    def __init__(self, course_name, course_price, course_time):
        self.course_name = course_name
        self.course_price = course_price
        self.course_time = course_time

    # 定义打印课程方法   : 只打印一个课程信息
    def tell_course_info(self):
        print(f'''
        ====== 课程信息如下 ======
        课程名称: {self.course_name}
        课程价格: {self.course_price}
        课程周期: {self.course_time}
        ''')


# 创建学生对象
stu1 = Student('HCY', 2000, 'female & male')
date_obj = Date('公元19', '11', '11')
stu1.date_obj = date_obj
# stu1.tell_birth()

# 创建课程对象
python_obj = Course('python', 77777, 6)
go_obj = Course('go', 88888, 4)

# 当前学生添加了课程对象
# 添加python课程
stu1.add_course(python_obj)
# 添加go课程
stu1.add_course(go_obj)

# 当前学生打印所有课程信息
stu1.tell_all_course_info()

 

 

三、封装

1、什么是封装?

封装是可以将一堆属性和方法,封装到对象中。

2、为什么要封装?

方便数据的存取。

可以通过《 对象.》的方式 存/取 属性或方法。

对象拥有<  .  >的机制。

3、如何封装?

class User:
    x = 10
    def func():
        pass
obj = User()
obj.y = 20
obj ---> x, func, y

 

四、访问限制机制

1、什么是访问限制机制?

凡是在内部定义的属性或方法,以__开头的属性或方法名,都会被限制,外部不能直接访问该属性原型。看起来就像将该属性或方法隐藏起来了。

python特有的:

凡是在类内部定义__开头的属性或方法,都会变形为_类名__属性/方法。

2、为什么要有访问限制?

比如:将一些隐私的数据隐藏起来,不然外部轻易获取。

但其实可以间接访问,通过接口:

将一堆数据封装成一个接口,可以让用户调用接口,并且通过相应的逻辑,最后再将数据返回给用户。

3、实现方法:

demo1

class User:
    #开头的属性
    __name = 'aaa'  #__name变形为 _类名__属性名

    #开头的方法
    def __run(self):
        print('running...')

# print(User.__name)
#AttributeError: 'User' object has no attribute '_User__name'

# obj = User()
# print(obj._User__name)  #ccc

demo2

class User:

    __name = 'aa'
    __age = 11
    __sex = 'male'
    __ID = '45687474643232342'
    __bal = 34464532

    # 校验接口,获取用户信息
    def parse_user(self, username, pwd):
        if username == 'aa' and pwd == '123':
            print(f'''
            用户名:{self.__name}
            年龄:{self.__age}
            性别:{self.__sex}
            ID:{self.__ID}
            资产:{self.__bal}
            ''')
        else:
            print('校验失败,无法查询用户信息!')


    def __run(self):
        print('running...')

# obj = User()
# obj.parse_user('aa','123') #成功
# obj.parse_user('aa','3')   #失败

demo3

class People:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    # 添加课程
    def add_course(self, course_obj):  # self ---> stu1
        # self.course_name = course_name
        # self.course_price = course_price
        # self.course_time = course_time
        # self.course_list.append(course_obj)  # [课程对象1, 课程对象2, ...]
        self.course_list.append(course_obj)  # [python_obj, go_obj]

    # 打印当前对象中课程列表的所有课程信息
    # ---》 打印所有课程
    def tell_all_course_info(self):  # self ---> stu1

        # 从当前对象中课程列表中取出所有的课程对象
        # self.course_list == [python_obj, go_obj]
        for course_obj in self.course_list:

            # 1.course_obj ---> python_obj
            # 2.course_obj ---> go_obj

            # 通过课程对象.打印课程信息方法
            course_obj.tell_course_info()  # python_obj.tell_course_info()  go_obj.tell_course_info()


class Student(People):
    # 假设从程序开始到灭亡  在实例化时都不修改该对象的属性
    def __init__(self, name, age, sex):
        super().__init__(name, age, sex)

        # 为当前对象添加课程列表属性 ---》 []
        self.course_list = []


class Teacher(People):
    def __init__(self, name, age, sex):
        super().__init__(name, age, sex)

        # 为当前对象添加课程列表属性 ---》 []
        self.course_list = []


# 定义一个课程类: 课程有: 课程名称, 课程价格, 课程周期
class Course:
    def __init__(self, course_name, course_price, course_time):
        self.course_name = course_name
        self.course_price = course_price
        self.course_time = course_time

    # 定义打印课程方法: 只打印当前课程信息
    def tell_course_info(self):
        print(f'''
        ====== 课程信息如下 ======
        课程名称: {self.course_name}
        课程价格: {self.course_price}
        课程周期: {self.course_time}
        ''')


# 学生对象stu1:  属性: name, age, sex, course_list   方法: add_course,  tell_all_course_info
stu1 = Student('xxx', 18, 'female')

# 课程对象:  属性: course_name, course_price, course_time    方法: tell_course_info
python_obj = Course('python', 20000, 6)
go_obj = Course('go', 28000, 5)

# 学生调用添加课程功能
stu1.add_course(python_obj)
stu1.add_course(go_obj)

# 学生调用打印 学生课程列表中所有课程的信息
stu1.tell_all_course_info()

 

posted @ 2019-11-27 17:58  小猪皮蛋  阅读(240)  评论(0编辑  收藏  举报