day08-面向对象进阶

day08 面向对象进阶

在 用户\AppData\Roaming\Typora
按照修改日期排序
删除最近修改的那些文件

  1. 内容回顾
    # 序列化
    # json
    # json类型 : ‘{“key”:[1,2,3]}’
    # 所有语言通用的\支持的数据类型有限
    # 序列化的结果是字符串 : 可视化
    # json不支持多次dump
    # pickle
    # python自己用\支持python中几乎所有的数据类型
    # 结果是二进制 :看不懂的
    # pickle天生支持多次dump和load
    # 面向对象
    # 类 class 类型
    # 类变量
    # 实例方法 init attack bite
    # 类指针 - 指向父类
    # 对象
    # 对象指针
    # 实例变量 self.name slef.age
    # 组合
    # 一个对象作为一个属性
    # self.course = python
    # 继承
    # class Foo:pass
    # class Son(Foo):pass
    # Son是子类\派生类 Foo是父类\超类\基类
    # 继承的特点:
    # 如果多个类都用到了相同的方法\属性
    # 我们应该把这些共用的方法抽象到他们的父类中去
    # 减少代码的冗余
    # 先写子类的功能,发现重复才创建父类
    # 子类自己没有某一个方法或者属性的时候用父类的
    # 如果自己有 还像用父类的 在子类中直接调用父类的方法就可以了

  2. 今日内容
    # 继承进阶
    # super语法
    # py2 和 py3 – 继承顺序
    # 封装
    # 私有的概念
    # property \classmethod \staticmethod
    # 双下方法
    # new
    # str
    # 反射

    # 模块
        # 模块的导入
        # 包的导入
        # 项目名称
    
  3. pickle和json
    dic1 = {‘k1’:‘v1’}
    dic2 = {‘k2’:‘v2’}
    import json
    import pickle
    # with open(‘file’,‘w’) as f:
    # # ‘{“k1”: “v1”}’ + ‘\n’
    # json.dump(dic1,f)
    # json.dump(dic2,f)

    # with open('file','rb') as f:
    #     ret1 = pickle.load(f)
    #     ret2 = pickle.load(f)
    #     print(ret1)
    #     print(ret2)
    
    with open('file','w') as f:
        ret = json.dumps(dic1)
        f.write(ret+'\n')
        ret = json.dumps(dic2)
        f.write(ret + '\n')
    
    with open('file','r') as f:
        for line in f:
            line = line.strip()
            if line:
                dic = json.loads(line)
                print(dic)
    
  4. super语法
    class Course:
    course_lst = []
    def init(self,name,period,price):
    self.name = name
    self.period = period
    self.price = price

    class Role:
        def __init__(self,name):
            self.name = name
        def show_course(self):
            for item in Course.course_lst:
                print(item.name,item.period,item.price)
    
    class Student(Role):
        def __init__(self,name):
            # Role.__init__(self,name)
            # super(Student, self).__init__(name)
            super().__init__(name)   # super也可以帮助我们找到父类
            self.courses = []
    
    class Manager(Role):pass
    
    python = Course('python','6 months',19800)
    linux = Course('linux','5 months',17800)
    Course.course_lst = [python,linux]   # 所有的可选课程
    
    m = Student('alex')
    print(m.name)
    m.show_course()
    
  5. 多继承

    class A:
        pass
        def func(self):
            print('in A')
    
    class C(A):
        pass
        # def func(self):
        #     print('in C')
    
    class B(A):
        pass
        # def func(self):
        #     print('in B')
    
    class D(B):
        pass
        # def func(self):
        #     print('in D')
    class E(C):
        pass
        # def func(self):
        #     print('in E')
    
    class F(D,E):
        pass
        # def func(self):
        #     print('in F')
    # f = F()
    # f.func()
    print(F.mro())  # 查看多继承中的继承顺序
    # 顺序 遵循C3算法
    
    # 重新认识super
    # class D:
    #     def func(self):print('D')
    # class C(D):
    #     def func(self):
    #         super().func()
    #         print('C')
    # class B(D):
    #     def func(self):
    #         super().func()
    #         print('B')
    # class A(B,C):
    #     def func(self):
    #         super().func()
    #         print('A')
    
    # a = A()
    # a.func()
    
    # b = B()
    # b.func()
    
    
    # 在单继承中 super的作用就是找父类
    # 在多继承中 super是找mro顺序的下一个类
    
  6. object类
    object
    有很多xxx方法
    init方法也在object类中
    object类
    在python3.x的所有类都是object的子类
    所以对于一些内置的方法会写在object类中
    如果子类不定义,在调用的时候最终会调用object类中的方法
    就不会让程序出现不必要的错误了
    init方法就是其中的一个例子
    所有继承了object类的类 ---- 新式类
    在python2中 不继承object类的都是 经典类
    # class A(object):
    # pass # 新式类

    # class A:
    #     pass   # 经典类 :在多继承中遵循深度优先
                 # 经典类中没有super和mro方法
    

    把面向对象的基础知识掌握之后才来深入的了解复杂的继承关系
    所有的py3中 的类都继承object 是新式类
    在继承中 遵循 广度优先的 C3算法
    也可以使用mro来查看继承顺序
    super这个方法 可以帮助我们查找到mro顺序中的下一个类

  7. 封装
    # 三大特定 : 继承 封装 多态
    # 封装
    # 人狗大战
    # 规范的创建对象
    # 创建的所有人的属性名都能一致
    # 把所有的方法装进一个角色中
    # 广义上的封装 : 把方法和变量都封装在类中
    # 在类的外部就不能直接调用了
    # 狭义上的封装 : 在类的外部干脆不能调用了

    # class Student:
    #     def __init__(self,name):
    #         self.__name = name  # 把name这个属性私有化了
    #     def get_name(self):
    #         return self.__name
    #     def set_name(self,value):
    #         if type(value) is str:
    #             self.__name = value
    #
    # 老王 = Student('老王')
    # print(老王.get_name())
    # 老王.set_name(1010101010100010)
    # print(老王.get_name())
    # print(老王.__name)
    
    
    # class Person:
    #     def __init__(self,username,password):
    #         self.username = username
    #         self.__password = password
    #
    # p = Person('alex','alex3714')
    # print(p.username)
    
    # class A:
    #     __val = []
    #     def __init__(self):
    #         print(A.__val)
    #
    # A()
    # print(A.__val)
    
    # class A:
    #     def func(self):
    #         self.__aaa()
    #     def __aaa(self):
    #         print('aaa')
    
    # a = A()
    # a.func()
    
    # 在类的内部 ,实例变量(对象属性)可以变成私有的,类变量可以变成私有的,实例方法也可以变成私有的
    # 一旦变成私有的就只能在类的内部使用,而不能在类的外部使用了
    
    # 私有化到底是怎么做到的 :只是在类内部使用的时候对名字进行了包装 变成了_类名xxxx
    # class B:
    #     __abc = 123  # _类名xxxx
    #     print(__abc) # 使用 都会由这个类进行一个变形 _类名xxxx
    # print(B.__dict__)
    # print(B.__abc)
    
    # 私有的变量不能被继承
    # class A:
    #     def __func(self):   # _A__func
    #         print('in A')
    #
    # class B(A):
    #     def wahaha(self):
    #         self.__func()   # _B__func
    #
    # b = B()
    # b.wahaha()
    
    # 毕业练习题
    # class A:
    #     def __init__(self):
    #         self.__func()    # self._A__func
    #     def __func(self):   # _A__func
    #         print('in A')
    #
    # class B(A):
    #     def __func(self):   # _B__func
    #         print('in B')
    #
    # b = B()
    
    # 在哪个类中调用方法,就在这个私有方法之前加上这个类中的变形
    # 和self本身是谁的对象都没有关系
    
  8. 多态
    在python中处处是多态
    # 在python中处处是多态
    # def func(int a,int b,int c):
    # pass
    # java是比较严谨的,所有在传递参数的时候必须指定参数的类型才可以

    # class User:pass
    # class Student(User):pass
    # class Manager(User):pass
    #
    # def change_pwd(person):
    #     pass
    # 希望指定的类型 既能够保证 学生对象能传进来  管理员也能传进来
    
    # print(type('123'))
    # alex = Manager()
    # print(type(alex))
    # 周老板 = Student()
    # print(type(周老板))
    
    # User这个类可以表现出多种状态 :学生的状态  管理员的状态
    
  9. 面向对象的装饰器
    # class Student:
    # def init(self,name,birth):
    # self.name = name
    # self.birth = birth
    #
    # @property # 将一个方法伪装成属性
    # def age(self):
    # import time
    # return time.localtime().tm_year - self.birth
    # alex = Student(‘alex’,1930)
    # print(alex.age) # 名词

    class Circle:
        def __init__(self,r):
            self.r = r
    
        @property
        def area(self):
            return 3.14*self.r**2
    
        @property
        def perimeter(self):
            return 2*3.14*self.r
    
    c = Circle(10)
    print(c.area)
    print(c.perimeter)
    
  10. classmethod和staticmethod
    class Student:
    def init(self,name):
    self.name = name
    @staticmethod # 声名login方法是一个静态方法 ,不必传任何默认的参数
    def login(flag):
    print(‘登录程序’,flag)
    username = input(‘>>>’)
    stu = Student(username)
    return stu
    # 要想调用login 必须现有对象
    # 要想创建对象 必须用户先输入名字
    # 得调用登录之后才开始input

     # 不必实例化就可以调用的login方法 不需要传递对象作为参数,就定义这个方法为静态方法
     obj = Student.login(flag = True)  # 用类名可以直接调用这个方法了
     print(obj.__dict__)
    
     class Manager:
         def __init__(self,name):
             self.name = name
         @classmethod     # 装饰当前这个方法为一个类方法,默认传参数cls,表示当前所在的类名
         def login(cls):
             username = input('>>>')
             stu = cls(username)
             return stu
    
     obj = Manager.login()  # 用类名可以直接调用这个方法了
     print(obj.__dict__)
    
    
     class A:
         def func(self):  pass  # 实例方法 self作为默认参数,需要用对象来调用
    
         @classmethod
         def func1(cls):  pass  # 类方法 cls作为默认参数,可以用类名来调用
    
         @staticmethod
         def func1():  pass  # 静态方法方法 没有默认参数,可以用用类名来调用
    
  11. 内置方法
    # 凡是数据类型 都会或多或少带有一些 双下方法
    # xxxx 魔术方法 内置方法
    # 调用的时候总是不好好调用

    # 'abc'.split('b')  # 正经调用str类型的split方法
    # ret = 'abc'.__add__('efg')
    # print(ret)
    # print('abc' + 'edf')
    
    # __str__
    class Course:
        course_lst = []
        def __init__(self,name,period,price):
            self.name = name
            self.period = period
            self.price = price
        def __str__(self):
            return '%s,%s,%s'%(self.name,self.period,self.price)
    # python = Course('python','6 months',19800)
    # linux = Course('linux','5 months',17800)
    # Course.course_lst = [python,linux]
    # for course in Course.course_lst:
    #     print(course)  # 打印一个对象总是打印内存地址,这个数据对我们来说没有用
        # 打印这个对象的时候查看这个对象的相关信息
        # print(obj) 打印一个对象 总是调用obj.__str__(),打印的是这个方法的返回值
    
    __new__
    class A(object):
        def __new__(cls, *args, **kwargs): # 构造方法 开辟空间 构造对象的方法
            obj  = object.__new__(cls)
            return obj
    
        def __init__(self):       # 初始化方法
            print('init : ',self)
            self.name = 'alex'
    
    # 1.创建一块空间 : __new__
    # 2.调用init
    # A()
    
    # 算法导论 - 微观
    # 23个设计模式 - 宏观
    
    # java语言
    
    # 单例模式 - 只创建一个实例
    # class A:
    #     pass
    #
    # a1 = A()
    # a2 = A()
    # print(a1)
    # print(a2)
    
    class Singleton:
        __instance = None
        def __new__(cls, *args, **kwargs):
            if not cls.__instance:
                obj = object.__new__(cls)
                cls.__instance = obj
            return cls.__instance
    
        def __init__(self,name):
            self.name = name
    
    obj1 = Singleton('alex')
    obj2 = Singleton('wusir')
    print(obj1.name,obj2.name)
    
    # 什么是单例模式?、
    	# 在多次实例化地过程当中只会产生一个实例,
    # 怎么实现
        # 用new实现
        # new做什么用 在什么时候执行
        	# new方法是开空间用的,在init之前执行
    
  12. 反射
    # 什么是反射
    # 如果有一个变量名 是字符串数据类型的 你能获取到这个变量的值么?
    # class Student:
    # def init(self):
    # self.name = ‘alex’
    # self.age = 80
    # self.gender = ‘male’
    #
    # def show_info(self):
    # print(‘%s,%s’%(self.name,self.age))
    # stu = Student()
    # content = input(‘>>>’)
    # if hasattr(stu,content):
    # name = getattr(stu,content) # stu.show_info name=showinfo的地址
    # if callable(name):
    # name()
    # else:
    # print(name)
    # if content == ‘name’:
    # print(stu.name)
    # elif content == ‘age’:
    # print(stu.age)
    # elif content == ‘gender’:
    # print(stu.gender)

    # 对象的反射
        # hasattr(对象,'属性名') 判断对象是否有这个属性,有返回True
        # getattr(对象,'属性名') 返回对象中属性名对应的值
    # 反射属性
        # val = getattr(对象,'属性名')
            # val就是属性的值
    # 反射方法
        # val = getattr('对象','方法名')
            # val就是方法的地址
            # val() ==> 调用方法
    
    # 类的反射
    # class A:
    #     role = 'China'
    # print(getattr(A,'role'))  # 用类获取类的变量
    
    # 模块的反射
    # import time
    # print(time.time())
    # print(getattr(time,'time')())
    
    # 反射
        # a.b ===== getattr(a,'b')
    
    # name = 'alex'
    # age = 84
    # def func(*args):
    #     print('wahaha')
    # class Student:pass
    
    
    # import sys
    # print(getattr(sys.modules[__name__],'name'))
    # print(getattr(sys.modules[__name__],'age'))
    # getattr(sys.modules[__name__],'func')(1,2,3)
    # print(getattr(sys.modules[__name__],'Student'))
    
  13. 模块和包

    # 模块
    # 什么是模块?
        # py文件
        # 自定义模块 把多行代码拆成多个文件 使得代码更加严谨清楚
    
    # 导入模块的话
        # from 模块 import 变量
        # import 模块
            # 模块.变量访问变量的值
    # 导入包
        # from 包.包.包 import 模块
            # 模块.xxx直接获取值
        # import 包.包.模块
            # 包.包.模块,xxx获取值
    # 无论是导入模块还是包,必须要保证被导入的模块和包所在路径在sys.path的列表中
    
  14. logging模块
    # import logging
    # fh = logging.FileHandler(filename=‘xxx.log’,encoding=‘utf-8’)
    # fh1 = logging.FileHandler(filename=‘xxx2.log’,encoding=‘utf-8’)
    # sh = logging.StreamHandler()
    # logging.basicConfig(level=logging.INFO,
    # handlers=[fh,sh,fh1],
    # datefmt=‘%Y-%m-%d %H:%M:%S’,
    # format=‘%(asctime)s - %(name)s[%(lineno)d] - %(levelname)s -%(module)s: %(message)s’)
    # logging.debug(‘debug message’) # 情况越轻
    # logging.info(‘info message’) # 信息类的日志
    # logging.warning(‘warning message’)
    # logging.error(‘error message’)
    # logging.critical(‘critical message’)

    # logging日志分为5个等级
    # 默认只显示warning等级以上的信息
    import logging
    from logging import handlers
    sh = logging.StreamHandler()
    rh = handlers.RotatingFileHandler('myapp.log', maxBytes=1024,backupCount=5)
    fh = handlers.TimedRotatingFileHandler(filename='myapp2.log', when='s', interval=5, encoding='utf-8')
    logging.basicConfig(level=logging.INFO,
                        handlers=[rh,fh,sh],
                        datefmt='%Y-%m-%d %H:%M:%S',
                        format='%(asctime)s - %(name)s[%(lineno)d] - %(levelname)s -%(module)s:  %(message)s')
    while True:
        logging.WARNING('')
    
  15. 异常处理
    opt_lst = [1,2,3,4]
    try:
    num = int(input(‘请输入序号 :’))
    print(opt_lst[num-1])
    except ValueError:
    print(‘请输入一个数字’)
    except IndexError:
    print(‘请输入1-4之间的数字’)

www.cnblogs.com/Eva-J/articles/7228075.html

你可能感兴趣的:(python)