继承json模块,并派生出新的功能
# 继承json模块中JSONEncoder,并且派生出新的功能
import json
from datetime import date, datetime
# print(datetime.now())
# print(type(datetime.now()))
list1 = [str(datetime.now())]
res = json.dumps(list1)
print(res)
class Myjson(json.JSONEncoder):
def default(self, o):
# 判断一个对象是否是一个类的实例化
if isinstance(o, datetime):
return datetime.strftime(o, '%Y-%m-%d %X')
else:
return super().default(self, o)
a = 12
res = json.dumps(a, cls=Myjson)
print(res)
结果:
["2019-11-27 14:21:56.464236"]
12
组合
什么是组合:
组合指的是一个对象中,包含另一个或多个对象
为什么要用组合:
减少代码的冗余
如何使用组合:
耦合度:
耦合度越高:程序的可扩展性越低
耦合度越低:程序的可扩展性越高
继承:
继承是类与类之间的关系,子类继承父类的属性和方法,子类与父类是一种“从属”关系
组合:
组合式是对象与对象之间的关系,一个对象拥有另一个对象中的属性与方法,是一种什么有什么的关系
# 用继承来写
# 父类
class People:
def __init__(self, name, age, sex, year, month, day):
self.name = name
self.age = age
self.sex = sex
self.year = year
self.month = month
self.day = day
def tell_birth(self):
print(f'''
=======出生年月日========
年: {self.year}
月: {self.month}
日: {self.day}
''')
# 教师类
class Teacher(People):
def __init__(self, name, age, sex, year, month, day):
super().__init__(name, age, sex, year, month, day)
# 学生类
class Student(People):
def __init__(self, name, age, sex, year, month, day):
super().__init__(name, age, sex, year, month, day)
tea1 = Teacher('lixiaoran', 24, 'female', 2019, 12, 12)
print(tea1.day, tea1.month, tea1.year)
tea1.tell_birth()
结果:
12 12 2019
=======出生年月日========
年: 2019
月: 12
日: 12
# 用组合来写
# 父类
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}
''')
stu1 = Student('libai', 24, 'female')
date_obj = Date(1992, 12, 12)
stu1.date_obj = date_obj
stu1.date_obj.tell_birth()
print(stu1.date_obj.year, stu1.date_obj.month)
结果:
=======出生年月日========
年: 1992
月: 12
日: 12
1992 12
'''
练习需求:
选课系统:
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.day_obj.day}
''')
# 添加课程
def add_course(self, course_obj):
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('yyx', 24, 'male')
date_obj = Date(1996, 7, 14)
stu1.date_obj = date_obj
# 创建课程对象
python_obj = Course('python', 7777, 6)
go_obj = Course('go', 8888, 8)
java_obj = Course('java', 8888, 14)
# 添加课程
stu1.add_course(python_obj)
stu1.add_course(go_obj)
stu1.add_course(java_obj)
stu1.tell_all_course_info()
结果:
=========课程信息如下========
课程名称: python
课程价格: 7777
课程周期: 6
=========课程信息如下========
课程名称: go
课程价格: 8888
课程周期: 8
=========课程信息如下========
课程名称: java
课程价格: 8888
课程周期: 14
封装
什么是封装:
封装指的是将一堆属性和方法,封装到对象中
ps:
对象就好比是一个“袋子/容器”, 可以存放一对属性和方法
存不是目的,目的是为了取,可以通过"对象"的方式获取属性或方法
为什么封装?
可以通过”对象.“的方式”存放/获取“属性或者方法。
对象拥有‘.’的机制,方便数据的存取
如何进行封装:
class User:
x = 10
def func():
pass
obj = User()
obj.y = 20
obj ---->x,func,y
访问限制机制
什么是访问限制机制:
凡是再类内部定义的属性和方法
以_开头的属性或方法名,都会被限制,外部不能直接访问该属性的原型
ps:看起来像是将该属性或者方法隐藏起来
这是pytho特有的;
注意:
凡是在类内部定义—开头的属性或者方法,都会变形为_ 类名 __属性/方法
为什么要有访问限制:
将一些隐私的数据,隐藏起来,不让外部轻易获取
接口:
可以将一对数据封装成一个接口,可以让用户调用接口
并且通过相应的逻辑,最后再将数据返回给用户
如何实现:
一:
class User:
__name = 'tank'
def __run(self):
print('你是我的!')
print(User._User__name)
obj = User()
obj._User__run()
tank
你是我的!
二:
class User:
__ID = '5472663'
__bal = 1000000
def __init__(self, name, age, sex):
self.__name = name
self.__age = age
self.__sex = sex
# 校验接口获取用户信息
def parse_user(self, username, password):
if username == 'tank' and password == '123':
print(f'''
通过验证,开始获取用户信息
用户名:{self.__name}
用户年龄:{self.__age}
用户性别:{self.__sex}
身份ID:{self.__ID}
用户的资产:{self.__bal}
''')
# 方法
def __run(self):
print('tank is running!')
obj = User('tank', 85, 'female')
obj.parse_user('tank', '123')
obj._User__run()
通过验证,开始获取用户信息
用户名:tank
用户年龄:85
用户性别:female
身份ID:5472663
用户的资产:1000000
tank is running!
什么是property:
是一个python内置的装饰器,可以装饰在”类内部的方法“上
可以将该方法调用方式由----》对象.方法()--------》对象.方法
为什么用property:
在某些应用场景下,调用的方法只是来获取计算后的某个值
必须通过 对象.方法() 方式调用,让该方法看起来像动词
让名词的方法,调用时更为合理
目的是为了,迷惑调用者,调用的方法误以为是属性
如何使用:
在方法前加上@property
class User:
def __init__(self, name, age, sex):
self.__name = name
self.age = age
self.sex = sex
@property
def name(self):
return self.__name
@name.setter
def name(self, value):
self.__name = value
@name.deleter
def name(self):
del self.__name
# 了解: 设置被property装饰后的方法
# 注意: 需要修改的方法名字要与被property装饰器后的方法一样
user_obj = User('cwj', 24, 'female')
user_obj.name = 'lishiming'
print(user_obj.name)
# del user_obj.name
# print(user_obj.name)
lishiming
del user_obj.name
# print(user_obj.name)
user_obj.name
AttributeError: 'User' object has no attribute '_User__name'