1 2 3 4

组合 封装 访问限制机制 property

继承的一点补充

继承json模块中的jsonencoder 并派生出新的功能

import json
from datetime import date,datetime
dict1 = {
    'time1':datetime.now() #'time1':str(datetime.now())
}                          #这样的字符串类型才可以使用
res = json.dumps(dict1)
print(res)
>>>>>>>>>>>>>
报错
###改用以下的方法操作###
class MyJson(json.JSONEncoder):#这个地方的是继承父类
    def default(self,o):###这个是一个判断o代表的是是不是一个序列化对象,会把字典res的每一个值都放进去代表o
        if isinstance(o,datetime):#判断一个对象是否有一个类的实例,把字典里面每一个值都做一下判断,是不是datetime的对象,
            return datetime.strftime(o,'%Y-%m-%d %X')  是的 就返回一个时间的字符串,datetime.now()就是一个datetime对象
        else:
            return super().default(self,o)  ###如果不是的就返回default处理

dict1 = {
    'time1':datetime.now(),
    'name':'tank'
}
#指定自定义的一个MyJson 派生类
res = json.dumps(dict1,cls = MyJson)##cls= 自定义的类   cls = MyJson是一个必须要有的东西
print(res)
>>>>>>>>>>>>>>>>
{"time1": "2019-11-27 14:53:20", "name": "tank"}

组合

1.夺命三问

1.什么是组合?

​ -组合指的是一个对象中,包含另一个或者多个对象。

2.为什么要用组合?

​ -减少代码的冗余

3.如何使用组合?

耦合度:

​ 耦--->莲藕:藕断丝连

​ -耦合度越高,程序的可扩展性越低

​ -耦合度越低,程序的可扩展性越高

​ -跟继承相比,组合的耦合度低,程序的可扩展性高

2.总结

-继承:

​ 继承是类与类的关系,子类继承父类哦的属性/方法,子类和父类是一种从属关系

-组合:

​ 组合是对象与对象的关系,一个对象拥有另一个对象中的属性和方法,是一种什么有什么的关系

#父类
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('tank',17,'male',2002,6,6)
stu1 = Student('Hcy',109,'female',1910,11,11)
print(tea1.name,tea1.age,tea1.sex)
tea1.tell_birth()
stu1.tell_birth()
>>>>>>>>>>>>>>>>>>>>>
tank 17 male

        年:2002
        月:6
        日:6
        

        年:1910
        月:11
        日:11

下面这个是组合的实现

#组合的实现
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):
        People.__init__(self,name,age,sex)

#学生类
class Student(People):
    def __init__(self,name,age,sex):
        People.__init__(self,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('Hcy',109,'female')
print(stu1.name,stu1.age,stu1.sex)
date_obj = Date(1090,11,11)
stu1.date_obj = date_obj ######组合这个的意思把= 右边的date_obj看作一个属性值赋值给对象stu1的属性date_obj,也可以这么表示,stu1.new_date = date_obj,相当于obj.name = 'david',这个样就把2个对象组合到一起了。
print(stu1.date_obj.year,stu1.date_obj.month,stu1.date_obj.day)
stu1.date_obj.tell_birth() 调用对象中的函数
>>>>>>>>>>>>>>>
Hcy 109 female
1090 11 11

        年:1090
        月:11
        日:11
        

组合的使用

'''
练习需求:
    选课系统:
        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_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')
date_obj = Date('公元19','11','11')
print(date_obj.year)
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()  ####对象.函数+()调用类中间的函数立即执行的
>>>>>>>>>>>>>>>>>
公元19

        年:公元19
        月:11
        日:11
        

        ======课程信息如下=====
        课程名称:python
        课程价格:77777
        课程周期:6
        

        ======课程信息如下=====
        课程名称:go
        课程价格:88888
        课程周期:4
        

3.封装

1.夺命三问?

1.什么是封装?

​ -封:比如一个袋子,封起来。

​ -装:比如一堆小猫小狗,装在袋子里。

​ -对象相当于一个袋子

​ 封装指的是可以将一堆属性和方法,封装在对象中。

​ PS:对象就好比一个“袋子/容器”,可以存放一对属性和方法;

​ PS:存不是目的,目的是为了取,可以通过“对象''方式获取属性或方法。

2.为什么要封装?

​ -可以通过”对象“的方式,”存放/获取“属性或方法

​ -对象有”.“的机制

​ -方便数据的存取

3.如何封装?

class User:
    x = 10
    def func(self):
        print('world')
obj = User()
obj.y = 20
print(obj.x,obj.y)######这个例子就是封装,把数据封装在对象里面
obj.func()
>>>>>>>>>>>>>
10 20
world

4.访问限制机制

1.夺命三问

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

​ -凡是在类内部定义的属性或方法

​ -以--开头的属性或者方法名,都会被限制,外部不能"直接访问",该属性原型

​ PS:看着是将该属性或方法隐藏起来

python特有的:

​ 注意:凡是在类内部定义--开头的属性或者方法,都将变形为-类名--属性/方法

2.为什么有访问机制?

​ -比如将一些隐私的数据,隐藏起来,不让外部轻易的获取

​ -接口:

​ 可以将一对数据封装成一个接口,可以让用户调用接口

​ 并且通过相应的逻辑,最后将数据返回给用户

3.如何实现?

class User:

    #__开头的属性
    __name = 'tank'#,__name 变形为 _类名__name
    def __run(self):
        print('tank is running...')

obj = User()
print(obj.__name)####报错
print(obj._User__name)
obj._User__run()
>>>>>>>>>>>>>>
tank
tank is running...

class User:
    __name = 'tank'
    __age = 17
    __sex = 'male'
    __ID = '123'
    __bal = '10000000'
    # 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}
            ''')
        else:
            print('校验失败,无法查询到用户')

obj = User()
obj.parse_user('tank','123')   ####正常的方法 不能获取里面的——变量的  可以用这个方式											操作
>>>>>>>>>>>>>
 通过验证,获取用户信息:
            用户名:tank
            用户年龄:17
            用户性别:male
            身份ID:123
            用户资产:10000000
#模拟取钱的操作
class ATM:
    def __insert_card(self):
        print('开始插卡...')

    def __input_pwd(self):
        print('输入密码...')

    def __input_money(self):
        print('开始吐钱')

    def __print_flow(self):
        print('打印流水账单...')
        #取款的规范接口
    def withdraw(self):#######这个操作是self.方式调用上面的函数
        
        self.__insert_card()
        self.__input_pwd()
        self.__input_money()
        self.__print_flow()

obj = ATM()
obj.withdraw()
>>>>>>>>>>>>>>>>>>>>>>
开始插卡...
输入密码...
开始吐钱
打印流水账单...

5.property

1.夺命三问

1.什么是property?

​ -是一个python的内置方法,可以装饰在”类内部的方法上“。

​ 就可以将该方法调用方式----》对象.方法() 变成-----》对象.方法

2.为什么用property?

PS:在某些场景下 调用的方法只是用来获取计算后的某个值;

PS:必须通过,对象.方法()方式调用,让该方法看起来像动词

​ -目的为了迷惑调用者,调用的方法误以为是属性 而不是方法

3.如何用?

#需求:计算人体的bmi指数
#体重/身高的平方
#value = weight /(height**2)
class User:
    def __init__(self,name,weight,height):
        self.__name = name
        self.weight = weight
        self.height = height
    @property
    def bmi(self):
        return self.weight/(self.height**2)
user_obj = User('Huyan',100,2)
print(user_obj.bmi)####调用bmi的函数的时候,就没有带括号,因为加了@property 给人感觉是
						属性而实际是方法
>>>>>>>>>>>>>>>>>
25.0

修改名字
class User:
    def __init__(self,name,weight,height):
        self.__name = name
        self.weight = weight
        self.height = height
    @property
    def bmi(self):
        return self.weight/(self.height**2)


    @property		#######这个原来的 也要写在上面的
    def name(self):
        return self.__name


    @name.setter######需要注意的是修改方法名字 要与property装饰器后的方法是一样的
    						要用setter来表示
    def name(self,value):
        self.__name = value

user_obj = User('Huyan',100,2)
# print(user_obj.bmi)
user_obj.name = 'david'
print(user_obj.name)
>>>>>>>>>>>>>>>>>
david

删除名字
class User:
    def __init__(self,name,weight,height):
        self.__name = name
        self.weight = weight
        self.height = height
    @property
    def bmi(self):
        return self.weight/(self.height**2)


    @property
    def name(self):
        return self.__name


    @name.deleter  ####把这个名字删除掉
    def name(self):
        del self.__name

user_obj = User('Huyan',100,2)
# print(user_obj.bmi)
del user_obj.name
print(user_obj.name)
>>>>>>>>>>>
AttributeError: 'User' object has no attribute '_User__name'

posted @ 2019-11-28 14:58  ^更上一层楼$  阅读(125)  评论(0编辑  收藏  举报