- 面向对象三大特征
- 类
- 对象
- 单继承
- super
- 类的约束
- 异常处理
- 类的私有成员
- 属性
- 反射
- isinstance和issubclass
- type
-
面向对象(类)三大特征
封装
指函数,模块,类,对象等,将一些数据或者内容封装到一个空间 , 可以调用
多态
指一种事物多种形态
python 默认支持多态(变量可以指向任意数据类型)
同⼀个变量a可以是多种形态。鸭子类型 :两个类中有相同的方法 ,继承
指子类(子类的对象)可以调用父类(基类)的属性与方法
鸭子类型:看着像鸭子就是鸭子.,A,B完全没有耦合性,但是某种意义上形成了一种标准.类
优点:
1,类是相似功能的集合体,组织结构更清晰
2,拥有上帝的思维,制作一个公共模板.从类名的角度分析:
1, 类名查看类中所有的属性
Human.__dict__
2, 类名操作单独属性. 万能的.
查:Human.mind
增:Human.emotion = '有情感'
改: Human.mind = '无脑'
删:del Human.mind类名调用方法(不推荐使用).
__init__里面不能有return 对象 : 类名+()就是实例化对象
三步: a,在内存中开辟一个对象空间. b,自动执行__init__方法,将对象空间传给self c,执行__init__方法,给对象空间封装属性.
对象
obj = Hunman('宝元',1000)
1),对象查看对象内所有的属性.
obj.__dict__
2),对象操作对象空间的单独属性
增: obj.sex = '男'
删: del obj.name
改:obj.age = 73
查: obj.name
3) ,对象查看类中的属性.
obj.mind
4)对象执行类中的方法.
obj.work()类空间与对象空间研究类
1)给对象封装属性:在__init__中,在类外面,在累的其他方法中
2) 给类封装属性:类的外部,累的内部
3)有了指针:对象找一个属性:先对象空间找类空间找父类找
类找属性:类空间找父类空间找
以上顺序不可逆
4)依赖关系:将一个类的类名或对象传入到另一个类的方法中
5)关联,组合,聚合关系是一种,:将一个类的对象或类名封装到另一个类的对象属性中
6)实现,继承关系单继承
好处
减少代码重复率,让类与类 产生关系,增强耦合性(高内聚,低耦合),使代码更规范,清晰化
对象查找属性
对象空间 -----> 类空间 -----> 父类....
类的查找属性
类空间 ------> 父类空间 ----> object.
单继承:对象既要执行父类的方法,又要执行子类的方法.
两种解决方式:
1,类名.方法名(参数(包括self)) 不依赖继承 A.__init__(self,name,age) 2,super().方法名(参数(不包括self)) 依赖继承 super().__init__(name,age)
Super()
Super(类名,self)是按照mro顺序执行下一个类,跳过指定类名
super() 不是执行父类的,他是严格按照mro的继承顺序执行下一个
python中类的分类:
python2x版本:
python2.2之前,只有经典类,python2.2之后出现了新式类.
经典类: 不继承object类. 多继承遵循深度优先. 深度优先: 从左至右,一条路走到底.
class A: pass
新式类: 继承object的类. 多继承遵循c3算法,mro的顺序执行.
class A(object):
pass
python3x版本: 所有类都默认继承object.
只有新式类. 新式类的多继承: C3算法.
查看继承顺序 :类名.mro()
obj=D() print(D.mro())
类的约束
指制定一个强制标准,轻质子类要有父类规定的方法
第一种方式 :Python最常用的方式.
class Payment: def pay(self,money): raise Exception('子类要定义pay方法!!!')
方法二 抽象类 接口类
指制定一个规范,强制子类必须有pay方法,如果没有,在你实例化的时候就会报错.
from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self,money):
pass
@abstractmethod
def f1(self):
pass
class Alipay(Payment):
异常处理
错误类型:KeyError IndexError ValueError
1)单支:
try: 代码 Except 错误类型: 处理方式
2)多分支:
Try: 代码 Except 错误类型: 处理方式 Except 错误类型: 处理方式
3)万能异常
try: 代码 except Exception: 处理方式
如果 你只想将异常处理掉,对错误信息不关心,用万能异常.
4)多分支 + 万能
try: 语句 Except 错误类型: Print(‘’) Except 错误类型: Print(‘’) except Exception: 处理方式
else : 如果出现异常,就不执行else 否则执行else语句.
5) try except else:
6)try finally:
finally 出不出现异常都执行,异常出现前执行fianlly.
用途:
1.关闭文件句柄,关闭数据库链接. 2.函数return之前能够执行finally代码. 3.break之前可以执行finally.
7) raise 主动抛出异常
raise IndexError('超出索引范围')
8) 断言 表示一个强硬的态度,不满足条件直接报错
assert 条件 assert 1 == 2
类的私有成员
私有静态属性,私有对象属性,私有方法 都只能在内部使用
私有成员只是做了一个简单的变相加密,让你直接访问不了
私有成员来说,他们只能在类的内部使用, __age =”32”2个下划线叫私有
def __init__(self): self.__func() # self._A__func()
方法包括
普通方法(实例方法)、静态方法和类方法,
实例方法
通常是通过对象去调用的方法,主动将对象传给self
静态方法和类方法, 用 类名调用方法(对象也行,最好不用),
1)@classmethod类方法(cls), 第一个参数主动接受类名
2)@staticemethod静态方法:不依赖于类以及对象的方法,他是函数
属性@property
将方法伪装成了属性,代码级别上没区别,只是看起来更合理
1)类里面加上@property, 调用的时候不加括号
print(p1.bim)
要是不加,调用的时候加括号
print(p1.bim())
property的三个方法
@property @bmi.setter @bmi.deleter
class A: def __init__(self): self.bmi=100 @property def bmi(self): print(11) @bmi.setter def bmi(self,n): print(n) @bmi.deleter def bmi(self): print(111) obj=A() obj.bmi 触发被property obj.bmi=22 对bmi这个属性进行更改,就会触发被bmi.setter装饰的函数 del obj.bmi 触发deleter
坑 注:要是对象自己的属性与类的伪装重名时,对对象属性进行修改时,则只会执
@bmi.setter这个方法
class Foo: def get_AAA(self): print('get的时候运行我啊') def set_AAA(self, value): print('set的时候运行我啊') def delete_AAA(self): print('delete的时候运行我啊') AAA = property(get_AAA, set_AAA, delete_AAA) # 内置property三个参数与get,set,delete一一对应 f1 = Foo() f1.AAA f1.AAA = 'aaa' del f1.AAA
类与类之间的关系
继承关系:分为单继承,多继承
依赖关系: 将一个对象或者类名封装到另一个类方法中.
组合关系: 将一个对象封住到另一个对象的属性中.
class A: def func(self, a): print(a.name) def func1(self, a): self.q = a class B: def __init__(self): self.name = 'alex' # 依赖关系 obj1 = A() obj2 = B() obj1.func(obj2) # 组合 obj1 = A() obj2 = B() obj1.func1(obj2)
反射
指通过字符串的形式操作对象相关的属性
对象:实例化对象,类,本模块,其他模块
反射四个方法
检测是否含有某属性hasattr()
获取属性 getattr()
设置属性 setattr()
setattr(foo,'height',12) print(obj.__dict__) 删除属性 delattr()
用反射写一个登录页面
在本模块中
def foo(): print(11) import sys r=sys.modules[__name__] con=input('>>') if hasattr(r,con): getattr(r,con)()
函数与方法的区别
1.1)类中的实例方法只有通过对象调用时才叫方法,其次都是函数
2)类中的类方法,是方法MethodType
3)类中的静态方法,其实是函数FunctionType
2.区别:
函数是显性传参
函数不依赖对象,类
方法是隐性传参
方法依赖对象,类
3.用isinstance判断是方法还是函数
4.isinstance和issubclass的用法
isinstance(obj,A) obj 是否是A或A的派生类的对象 issubclass(B,A) 判断B是否是A的子类或孙类
Iterable: list,str,tuple,dict等都是Iterable的子类(派生类)
from collections import Iterable
print(isinstance(list,Iterable)) #False
print(isinstance([1,2,3],Iterable))#True
print(issubclass(list,Iterable))#True
type
type 元类,也叫构建类,type产出了python的大量的内类(object,str等等)以及自建类(自己建的类),python中一切皆对象
callable 判断可调用
双下方法
__new__和__init__区别
__new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例对象,是个静态方法。
__init__是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值,通常用在初始化一个类实例的时候。是一个实例方法。
1) new
也叫构造方法 new(cls)
类名()触发new方法 产生并返回对象的地方得有return
写一个单例模式
class A : def __init__(self): print(11) def __new__(cls, *args, **kwargs): print(22) return object.__new__(cls) obj = A() print(obj)
先执行__new__再执行__init__
class A: a = None def __new__(cls, *args, **kwargs): if not cls.a: obj = object.__new__(cls) cls.a = obj return cls.a d1 = A() d2 = A() print(d1,d2)
2) call
对象() 或者 类()()时触发__call__
3)item系列 :
类似于字典的操作
Getitem(获取): obj[‘name’]就会触发getitem setitem(修改): obj[‘name’]=’fd’就会触发setitem, 不写return这个单词 delitem(删除):del obj[‘name’] 不需要返回值 没有真删,把值传给了key class A: def __init__(self,n): self.name=n def __getitem__(self, item): print(12) return self.__dict__[item] def __setitem__(self, key, value): print(45) self.__dict__[key]=value def __delitem__(self, key): print(12) obj =A('xiaoh') print(obj['name']) #结果12 xiaoh obj['name']='df' print(obj.__dict__)#{'name': 'df'} del obj['name'] print(obj.__dict__) 没有真删,把值传给了key
还有一个attr的操作,跟item类似
它是点的操作
getattr(获取): obj.name 就会触发getitem setattr(修改): obj.name=’fd’就会触发setitem, 不写return这个单词 delattr(删除):del obj.name 不需要返回值 没有真删,把值传给了key
举个例子
class foo(object): def __setitem__(self, key, value): print(1) print(key,value) def __setattr__(self, key, value): print(2) print(key,value) f = foo() f.num=666 f['name'] = 888
结果是
2 num 666 1 name 888
4)len
只要对 对象len+(),就会触发对象从属于的类中的__len__方法 有return
写上len(obj)就会触发__len__ 不执行return结果
Print(len(obj)) 执行return结果
class A: def __init__(self,n,m,l): self.name=n self.m=m self.p = l def __len__(self): print(55) return len(self.__dict__) obj=A('bbn','hj','dasd') print(len(obj)) print(obj.__dict__)
结果是
55 3 {'name': 'bbn', 'm': 'hj', 'p': 'dasd'}
5) 上下问管理
enter exit
对一个对象类似于with的操作
class A: def __init__(self,a): self.a=a def __enter__(self): self.b=self.a+'小花' return self def __exit__(self, exc_type, exc_val, exc_tb): self.c='小兰字' with A('小兰') as f: #开始执行 print(f.b) print(f.c) #结束执行
6) hash
父类中有,所以不写也能触发__hash__
7) str
对象触发__str__ return后边是字符串
Print(obj) 触发__str__
class A: def __init__(self,n): self.name=n def __str__(self): return str(self.__dict__) obj =A('cbv') print(obj) #结果{'name': 'cbv'}
8) repr
return后边也是字符串
9) eq
同一个类的两个对象比较,就会触发__eq__方法
不写return 返回的是None
class A: def __eq__(self, other): print(12) return 456 obj =A() a=A() print(obj==a)
10)析构方法 del
当对象在内存中释放时,自动触发执行,此方法一般无需执行
11)iter 和__next__
class A: def __iter__(self): yield 1 yield 2 obj = A() # print(next(obj)) 会报错 因为obj是可迭代对象 obj1 = iter(obj) print(next(obj1)) print(next(obj1)) 结果是 1 2
或者
for i in obj: print(i) # 11 22
或者
print(list(obj)) #[11, 22]
来源:https://www.cnblogs.com/xm-179987734/p/12313042.html