day08 面向对象进阶
在 用户\AppData\Roaming\Typora
按照修改日期排序
删除最近修改的那些文件
-
内容回顾
# 序列化
# 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是父类\超类\基类
# 继承的特点:
# 如果多个类都用到了相同的方法\属性
# 我们应该把这些共用的方法抽象到他们的父类中去
# 减少代码的冗余
# 先写子类的功能,发现重复才创建父类
# 子类自己没有某一个方法或者属性的时候用父类的
# 如果自己有 还像用父类的 在子类中直接调用父类的方法就可以了 -
今日内容
# 继承进阶
# super语法
# py2 和 py3 – 继承顺序
# 封装
# 私有的概念
# property \classmethod \staticmethod
# 双下方法
# new
# str
# 反射# 模块 # 模块的导入 # 包的导入 # 项目名称
-
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)
-
super语法
class Course:
course_lst = []
def init(self,name,period,price):
self.name = name
self.period = period
self.price = priceclass 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()
-
多继承
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顺序的下一个类
-
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顺序中的下一个类 -
封装
# 三大特定 : 继承 封装 多态
# 封装
# 人狗大战
# 规范的创建对象
# 创建的所有人的属性名都能一致
# 把所有的方法装进一个角色中
# 广义上的封装 : 把方法和变量都封装在类中
# 在类的外部就不能直接调用了
# 狭义上的封装 : 在类的外部干脆不能调用了# 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本身是谁的对象都没有关系
-
多态
在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这个类可以表现出多种状态 :学生的状态 管理员的状态
-
面向对象的装饰器
# 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)
-
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 # 静态方法方法 没有默认参数,可以用用类名来调用
-
内置方法
# 凡是数据类型 都会或多或少带有一些 双下方法
# 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之前执行
-
反射
# 什么是反射
# 如果有一个变量名 是字符串数据类型的 你能获取到这个变量的值么?
# 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'))
-
模块和包
# 模块 # 什么是模块? # py文件 # 自定义模块 把多行代码拆成多个文件 使得代码更加严谨清楚 # 导入模块的话 # from 模块 import 变量 # import 模块 # 模块.变量访问变量的值 # 导入包 # from 包.包.包 import 模块 # 模块.xxx直接获取值 # import 包.包.模块 # 包.包.模块,xxx获取值 # 无论是导入模块还是包,必须要保证被导入的模块和包所在路径在sys.path的列表中
-
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('')
-
异常处理
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