Python_面向对象
一、内容回顾
成员
class Person:
def __init__(self, name, num, gender, birthday):
# 成员变量
self.name = name
self.num = num
self.gender = gender
self.birthday = birthday
# 对象来访问(成员方法)(实例方法)
def eat(self,name):
print("%s吃东西"%self.name)
### 成员:在类定义的变量和方法都被称为成员
变量:
1、成员变量(实例变量)、字段
2、类变量(静态变量)
方法:
1、成员(实例)方法,加了self的,调用的时候,必须用对象去访问
2、类方法 @classmethod def clsMethod(cls) ## 类方法:第一个参数传递的是类名
3、静态方法,当你的方法不需要传递当前类的对象。语法规则:在方法上面加@staticmethod
------>>>>>说一说,静态方法、类方法和实例方法的区别
属性:
用方法描述我们的属性信息
@property ## 表示当前方法是一个属性, 方法的返回就是这个属性的值,不用加括号(就是属性),直接访问属性,实际上访问
的是xxx()方法,返回值就是属性值 ## 方法只能有一个参数,就是self,并且要return
注意:
1、@property 改变一个方法称为属性
2、这个方法只能有一个参数,self
3、必须要有return
私有:
只能在自己类中执行,__方法,__属性,__
二、类与类之间关系
1、依赖关系(紧密程度最低)(大象装冰箱)
最轻的一种关系
在方法中引入领一个类的对象
2、关联关系
类与类之间的关系是比较紧密的。
3、组合关系
4、聚合关系
5、继承关系、实现关系
self :当前执行这个方法的对象
三、类名和对象是否可以作为key
# 对可哈希,内部是否哈希算法 __hash__
1、 class Foo(object): ## 所有的类都会默认继承obj
def __init__(self):
pass
def func(self):
pass
__hash__ = None
dic = {}
dic[Foo] = '12344' ## 类名是可哈希的
dic[Foo()] = 'hello' ## TypeError : unhashable type:'Foo' 类中是否包含__hash__
print(dic)
## list dic set 内部中__hash__ = None , 是不可哈希的
eg:
self 到底是谁?
## self 当前访问xx方法的那个对象
四、类中的特殊成员
什么是特殊成员?__init__() 就是一个特殊的成员,带双下划先的那一坨,这些方法
在特殊的场景的时候会被自动的执行。
1、类名() 将 执行 __init__() 构造方法
2、对象() == >> obj() 会默认执行 __call__ ## python 特有
3、对象[] ==>> obj[xxxx ] 从对象中获取数据 默认执行 __getitem__()
4、对象[] = xxx == >> 默认执行 _setitem__()
5、del obj[key] 默认执行_-delitem__()
6、打印对象的时候 会自动执行 __str__()
7、with 对象 as 变量 会自动执行 __enter__ 和 __exit__()
__new__():
1、加载类
2、开辟内存空间
(开辟方法)
def __new__(cls,*args,**kwargs):
return object.__new__(cls) ## 这句话才是创建对象,其他都是初始化对象
3、初始化这一块内存__init __
五、issubclass 、 type 、isinstance
issubclass 判断xxxx类是否是xxx类的子类
type 给出xxx的数据类型
isinstance 判断对象是否是XXX家族体系的内容,往上找
区分方法和函数:
在外面定义的函数一定是函数
实例方法: 对象.方法 方法 类名.方法 函数
静态方法: 都是函数 @staticmethod
类方法: 都是方法 @classmethod
## 引入两个模块
from types import FunctionType, MethodType
def haha(arg):
print(isinstance(arg, FunctionType))
print(isinstance(arg, MethodType))
haha(XXX.class_method)
haha()
六、反射(重点)
getattr(obj,"xxx") ## 从xxx对象或者模块中找xxxx()的功能(字符串)
hasattr(obj,"xxx") ## 判断xxx对象或者模块存才"xxx"
setattr(obj,xxx1,xxx2) ## 修改 仅限于内存 动态的设置给对象属性和值
delattr(obj,"xxx") ## 删除 仅限于内存
callabel(func) ## 判断这个鬼东西时是否可以被调用
if hasattr(obj, "xxx"):
func = getattr(obj, "xxx")
if callable(func):
func()
else:
print(func())
else:
print("None")
七、面向对象的反射
def Person:
def __init__(self,name):
self.name = name
def chi(self):
print("chidongxi")
p = Person("你好")
# p.chi()
chi = hasattr(p,"chi")
chi() # ??
val = input("请输入:")
if hasattr(p, val):
attr = getattr(p, val)
attr()
八、约束和异常处理
(1)异常处理(处理、抛出异常、自定义异常)
1、产生异常:raise 异常类(),抛出异常
2、处理异常:
try :
xxx ## 尝试执行的代码
except 异常类 as 变量: ## 出现错误的时候,捕获到异常
xxxx ## 处理异常
3、自定义异常
继承Exception
4、堆栈信息
import traceback
traceback.format_exc() ## 获取堆栈信息
(2)约束(难)
一、通过抛出异常(简单,才是真正PYTHON中写法)
约束是对子类进行的约束(进行修改,统一)
在父类中给出一个方法。这个方法中什么都不写。就抛出异常,NotImplementError()
在子类中把上述的方法进行重写
重写:子类重新定义父类中的方法。
二、抽象类和抽象方法(java,C#)
from abc improt ABCMeta, abstractmethod
抽象方法:抽象方法不用给出方法体,写个pass
抽象类:
语法:类(metaclass = ABCMeta)
概念:如果类中包含了抽象方法,这个类一定是抽象类
特点: 抽象类一般不创建对象.
抽象类中可以存在正常方法
可以约束子类必须实现抽象方法
抽象(百度贴吧)
class Base:
def login(self):
raise NotImplementedError("没有实现login方法") ## 专业的写法
## 张三
class Normal:
def login(self):
print("普通人登录")
## 李四
class Member:
def denglu(self):
print("吧务登录")
## 王五
class Admin:
def login(self):
print("管理员登录")
def login(obj):
print("产生验证码")
obj.login()
print("进入主页")
#场景
n = Normal()
m = Member()
a = Admin()
login(n)
login(m)
login(a)
## 重写 :子类对父类提供的方法不满意,重新去定义这个方法
from abc improt ABCMeta, abstractmethod(抽象方法)
class Animal(metaclass = ABCMeta): ## 在父类中写出metaclass = xxx 抽象类
@abstractmethod ## 抽象方法
def chi(self): ## 抽象的概念,
pass
##def dong(self):
## print("123")
class Cat(Animal): ## 子类必须实现父类中的抽象方法
def chi(self): ## 具体的表现
pritn("猫爱吃鱼")
九、MD5加密
MD5加密:不可逆## (网站上的解密md5都是有(以前别人数据)查询)
引入模块 hashlib
(1) imoprt hashlib
## 1.创建一个md5加密
obj = hashlib.md5(b"sdf1asd45f6sadfg") ## 加盐
## 2.把要加密的内容给md5
obj.updata("123",encode("utf-8")) ## 必须是字节
## 3.获取密文
val = obj.hexdigest()
print(val)
def my_md5(val):
obj = hashlib.md5(b"asdf2sd1f")
obj.updata(val,encode = "utf8")
val = obj.hexdigest()
return val
## 注册的时候, 用md5进行加密, 存储的是加密后的密文
username = input("请输入你的用户名")
password = input("请输入你的密码")
cun = my_md5(password)
print(cun)
## 用户登录
if username == "xxx" and y_md5(password) == "xxxxxxxxxxxxxx":
print("登录成功")
else:
print("登录失败")
十、日志处理(重要、简单)
引入logging模块
logging.basicConfig(filename= 'xxx.log',
fromat = "%(name)s-%(levelname)s-%(module)s:%(message)s",
datefmt = "%Y-%m-%d %H :%M:%S",
level = 30) ## level 设置级别,当你的信息的级别>=level 的时候才会写入日志文件,默认30
## 写日志
logging.critical("xxxx")
logging.error("xxxx")
logging.info("xxxxx")
logging.debug("xxxx")
logging.log(int,"xxxx")
非必现bug
import traceback
for i in range(20):
try:
if i % 3 == 0:
raise FileNotFoundError("xxxxx")
elif i % 3 == 1:
raise StopIteration()
elif i % 3 == 2:
rause KeyError()
except FileNotFoundError as e:
val = traceback.format_exc()
logging.error(val)
except StopIteration as e:
val = traceback.format_exc()
logging.error(val)
except KeyError as e:
val = traceback.format_exc()
logging.error(val)
## 多文件日志处理
#创建一个操作日志的对象logger(依赖FileHandler)
filehandler=logging.FilelHandler('11.1og','a',encoding='utf-s')
filehandler.setFormatter(logging.Formatter(fmt="%(asctime)s-%(name)s-%(levelname)s-%(module)s:%(message)s"))
logger1=logging.Logger('s1',level=logging.ERROR)
logger1.addHandler(file_handler)
logger1.error("我是A系统")
#在创建一众操作旦志的对象loggar(依赖Filellandler)file_handler2=logging.FileHandler('12.1og','a',encoding='utf-8')
file handler2.setFormatter(logging.Focmatte'(fmt="%(asctim)s-%(name)s-%(levelname)s-%(module)s:%(message)s"))
logger2=logging.Logger('B',level=40)
logger2.addHandler(file_handler2)
logger2.error(”我是B系统")
十一、内容回顾
1、异常处埋
raise:抛出异常.
try:
可能会出现错误的代码
except 异常类ase:
异常的处理
except 异常类ase:
异常的处理
except 异常类as e:
异常的处理
except 异常类as e:
异常的处理
else:
如果上面的代码没有错误,执行这里的代码
finally:
收尾
自定义异常:随便写个类.继承Exception
2.约束
父类和子类.
在父类中声明方法.要求子类必须重写它
1.抛出异常.raise NotImplementError
2.抽象类和抽象方法
from abc import ABCMeta,abstractmethod在父类声明的时候,metaclass=ABCMeta
方法上面加@abstractmethod
子类必须重写这个抽象方法.
接口:定义方法和约束子类
3.MD5
1.引入模块
import hashlib
2.创建md5对象(实例化)
obj=hashlib.md5(b"盐")
3.把加密的内容交给md5
obj.update(bytes)
4.获取密文
obj.hexdigest()
4.日志
logging模块
basicConfig filename format datefmt level级别。
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTEST 0
十二、新式类和经典类的MRO(方法路径顺序)
class Base1:
def func(self):
super().func()#Base2里的func
print("娃哈哈")
class Base2:
def func(self):.
print("雪碧")
class Foo(Basel,Base2):#*Foo,Basel,Base2
pass
f=Foo()
f.func()
MRO(method resolution Order)方法路径顺序.
python2
1.使用经典类(写继承关系的时候.基类不继承object) , 所使用的是MOR是深度优先遍历
2.新式类(继承关系的根.是object)
python3
只有新式类
新式类的MRO,C3(重点,难点)
新式类中摒弃了(部分).C3算法如果你的继承关系中没有菱形继承(深度优先就够)。
如果有菱形:使用C3算法来计算MRO假设C3算法.是L(x)=x的继承关系号先拆分。拆到你能看出结果为止
反复进行merge(元组,元组。。。。、。。)运算
!!!摘头,头和尾在对比,如果下一个尾没有这个头,头就出现,如果出现,跳过该元组,继续下一个元组的头,反复,在回到上一个元组持续进行。
如果是简单的菱形继承,把头干掉。使用深部遍历,最后是头。
如果是复杂的菱形继承,需要C3算法, xxx.__mro__(),找到每个类的继承关系,然后拆分,再合并。
第一件事,先画图,看有没有菱形继承
十三、常用模块
(1)random
## 小数
random.random() ## 0-1小数
random.uniform(1,3) ## 1-3之间的小数
## 整数
random.randint(1,36) ## 【1-36】随机数
random.randrange(1,5,3) ## [1,5) 步长是3
##
random.choice(["xxx", "xxx", "xxxx"]) ## 随机选一个
random.sample(list[range(1,37)], 3) ##随机选3个
lst = [131,5,21,54,2,34,465,12]
random.shuffle(lst) # #洗牌
(2)Queue 队列 stack 栈
(3)collections
1、Counter
2、queue # 双端队列 d = queue()
3、namedtuple ## 定义一个简单的类
4、defaultdict
(4)time
time.time() ## 获取时间戳
time.strftime("%Y-%m-%d") ## 时间格式, 格式化时间
time.localtime() # 结构化时间 ,用来计算的
(5)os
os.makedirs("a/b/c") ## 创建多级目录
os.removedirs("a/b/c") ## 删除多级目录(不能有文件,对文件的一种保护)
os.listdir("xxx/") ## 列出指定文件目录下的所有文件和子目录, 包括隐藏文件,并以列表方式打印
os.remove() ## 删除一个文件
os.stat() ## 获取文件
os.system(“dir”) ## 直接执行shell 命令
os.popen("dir").read() ## 执行命令,返回结果
##os.path
os.path.split("xxx/xxx/xxx.xxx") ## 拆开
os.path.dirname(path)
os.path.exists(path) ## 判断路劲是否存在
os.path.join(path1,path2) ## 合并
## 特殊属性
os.sep ## 输出操作系统特点的路劲分隔符
os.linesep ## 输出当前平台使用的行终止符 win "\r\n" linux "\n"
os.pathsep ## 输出分割文件路劲的字符串
os.name ## win - > nt,NT, linux- > "posix"
(6)sys 模块
所有和python解释器相关的都在sys模块;
sys.argv 命令行参数LIST,第一个元素是程序本身路径
sys.version 获取Python解释程序的版本信息
sys.exit(0) 退出程序,正常退出是exit(0) ,错误退出sys.exit(1)
sys.path 返回模块的搜索路径,初始化时使用PYTHON环境变量的值
十四、序列化
1)pickle
## dumps 把对象转化成BYTES (序列化)
## loads bytes转化成对象 (反序列化)
## dump 把对象转化成bytes并写入文件
## load 把文件中的bytes读取,转化成对象
2)shelve
##提供python持久化操作
## open("文件")
f = shelve("xxxx") ## 相当于 f = {}
f["xxxx"] = "xxx"
f.close()
3)json
import json
dic = {"a":"xxx","b":"xxxxx","c","xxxxx"} ## 如果你的的k或者v超出ascii范畴,就会显示成\uxxxx
s = json.dumps(dic,ensure_ascii = False)
print(repr(s), type(s) ) ## 类型是str
## 把字符串解析成字典
dic = json.loads(s)
print(dic, type(dic) ) ## 类型是dict
## 写入的时候
1)循环
2)用dumps把字典转化成字符串, 然后手动在后面加一个\n
3)写出
## 读取的时候
1)for line in f:
2) strip() 去掉空白
3)loads()变成字典
4)configparser模块
该模块适用于配置文件的格式与windows ini 文件类似。
conf = configparser.ConfigParser()
conf["DEFAULT"] = {
"session-time-out" :30,
"user-alive":50
}
conf["189-DB"] = {
"ip":"189.135.1.1",
"port":"3306"
}
f = open("xxx.ini", mode = "w")
conf.write(f) ## 把文件扔进去
## 读取内容
conf = configparser.ConParser()
conf.read("xxx.ini")
conf.sections() ## 获取到章节
## 可以想字典一样操作