Python_面向对象编程
#三大编程范式 # 函数式编程 #代码量少但复杂 # 过程式编程 #将复杂的逻辑分解为一个个小的逻辑功能,从而完成大型复杂的项目的思路 # 面向对象编程 #利用对象的思想进行编程 # 利用函数模拟面向对象 if __name__=="__main__": #模拟类 def dog(name,color,type): #模式类的初始化 def init(name,color,type): #利用字典模拟初始化对象 dog={"name":name, #使模拟的对象拥有名字的属性 "color":color, #使模拟的对象拥有颜色的属性 "type":type, #使模拟的对象拥有类型的属性 "bark":bark, #使模拟的对象拥有bark函数的行为 "sleep":sleep,#使模拟的对象拥有sleep函数的行为 } return dog #返回实例化的对象 def bark(self): #bark函数 print("一条%s的狗:汪汪汪!"%self["color"]) #模拟某个对象的叫的功能 def sleep(self): print("一只%s正在睡觉!"%self["type"]) #模拟某个对象的睡觉的功能 return init(name,color,type) #返回实例化的对象 #利用函数模拟实例化对象的过程 dog1=dog("小黄","黄色","藏獒") #调用模拟的对象叫的功能 dog1["bark"](dog1) #利用模拟对象睡觉的功能 dog1["sleep"](dog1) #class #利用类完成面向对象 class完成面向对象比函数更加专业 #__init__ 将类实例化的函数 #self 指的是自己这个类的对象 # #对象拥有的两类元素: 1. 对象的数据属性, 2. 对象的函数属性 #用 . 访问对象属性或行为 class dog: #创建对象的类 def __init__(self,name,color,type): #将类的属性实例化对象 self.mingzi=name #给类的属性赋值 self.yanse=color self.leixing=type def bark(self): #定义类叫的行为 print("%s 的狗正在汪汪汪!"%self.yanse) def sleep(self): #定义类睡觉的行为 print("一只叫 %s 的 %s 正在睡觉!"%(self.mingzi,self.leixing)) dog2=dog("小黄","黄色","藏獒") #类实例化为对象 dog2.bark() #对象调用叫的行为 dog2.sleep() #对象调用睡觉的行为 # __dict__ 获取类或对象的属性字典 print(dog.__dict__) #获取类的属性 print(dog2.__dict__) #获取对象的属性 #面向对象的增删改查操作 #查询 print("这只狗叫 %s"%dog2.mingzi) #增 dog2.leg=5 print("这只叫%s的狗有%s条腿!"%(dog2.mingzi,dog2.leg)) #改 dog2.leg=4 print("这只叫%s的狗现在还剩%s条腿!" % (dog2.mingzi, dog2.leg)) #删 del dog2.leg #print(dog2.leg) AttributeError: 'dog' object has no attribute 'leg'
@property
#类存在两种属性: # 数据属性 # 函数属性 # @property 将函数属性的访问方式变为访问数据属性的方式 遵循了统一访问的原则 # 修饰类的函数属性 if __name__=="__main__": class dog: def __init__(self,name): self.name=name @property def sleep(self): return "%s 正在睡觉!"%self.name dog1=dog("小黄") #访问函数属性 print(dog1.sleep) #访问数据属性 print(dog1.name)
@classmethod类方法
# 类方法 #表示 @classmethod 修饰函数属性, #作用:使类访问函数属性,传进去的不是self,是一个cls的类 if __name__=="__main__": class dog: type="藏獒" def __init__(self,name): self.name=name @classmethod #使函数的访问对象改为类 def sleep(cls): return "一只 %s 正在睡觉!"%cls.type print(dog.sleep()) #类访问函数属性
静态方法 @staticmethod
#静态方法 @staticmethod #作用 把类中的函数定义为静态方法,为一个类定义不同的实例 if __name__=="__main__": class dog: def __init__(self,name): self.name=name @staticmethod def sleep(name): return "%s 正在睡觉!"%name @property def bark(self): return "%s 正在汪汪汪!"%self.name print(dog.sleep("小黄")) print(dog("小黄1").bark)
abc 抽象方法
#abc 抽象方法,需要其他类去实现,相当于定义了一个类的模板 #相当于java中的接口,通过实现类(接口)去实现 import abc #相当于接口模板 if __name__=="__main__": class animal(metaclass=abc.ABCMeta): @abc.abstractclassmethod def sleep(self): pass @abc.abstractclassmethod def bark(self): pass class dog(animal): def __init__(self,name): self.name=name @property def sleep(self): return "%s 正在睡觉!"%self.name @property def bark(self): return "%s 正在汪汪汪!" %self.name dog1=dog("小黄") print(dog1.sleep) print(dog1.bark)
继承
#面向对象的三种方式 #继承 #多态 #封装 #继承 class(class) #作用:使字类拥有父类的所有数据属性和函数属性,也可以对父类的数据和函数属性进行修改和添加 # super() 字类调用父类 if __name__=="__main__": class animal: def __init__(self,name,color): self.name=name self.type=type @property def sleep(self): print("%s 正在睡觉!"%self.name) @property def bark(self): print("%s 正在叫!"%self.name) class dog(animal): pass dog1=dog("小狗","藏獒") #默认使用父类animal的数据属性 dog1.sleep #默认使用父类animal的函数属性 dog1.bark #默认使用父类animal的函数属性 #super() 字类调用修改父类的方法 class cat(animal): def __init__(self,name,type,color): super().__init__(name,type) self.color=color @property def catchLaoShu(self): #新增方法 print("%s 捉了只老鼠!") cat1=cat("小黄","猫科","黄色") cat1.sleep cat.catchLaoShu
组合对象#组合对象 # 指将多个对象组合成一个对象 #组合人类 class head: def __init__(self,name,ey): self.name=name self.eye=eye(ey) print("生成 %s" % name) @property def think(self): print("%s 开始思考。。!" %self.name) class trank: def __init__(self,name): self.name=name print("生成 %s" % name) @property def stand(self): print("%s 站了起来!"%self.name) class foot: def __init__(self,name): self.name=name print("生成 %s" % name) @property def walk(self): print("%s 走起路来!"%self.name) class eye: def __init__(self,name): self.name=name print("生成 %s"%name) @property def see(self): print("%s 看东西!"%self.name) class hand: def __init__(self,name): self.name=name print("生成 %s"%name) @property def catchthing(self): print("%s 拿东西!"%self.name) class person: def __init__(self,name,hea,foo,tran,ey,han): self.name=name self.head=head(hea,ey) self.foot=foot(foo) self.tr=trank(tran) self.hand=hand(han) print("%s组合成功!"%self.name) @property def think(self): self.head.think @property def catch(self): self.hand.catchthing @property def stand(self): self.tr.stand @property def walk(self): self.foot.walk @property def watch(self): self.head.eye.see if __name__=="__main__": person1=person("小明","脑袋","脚","身体","眼睛","手臂") person1.think person1.stand person1.walk person1.catch person.watch
mro 类的访问顺序
#mro #指当前类找不到属性,去找下一个类的顺序 class A: def test(self): print("A") class B(A): def test(self): print("B") class C(B): def test(self): print("C") class D(C): def test(self): print("D") class I(A): def test(self): print("I") class H(I): def test(self): print("H") class G(H): def test(self): print("G") class E(D): def test(self): print("E") class F(E): # def test(self): # print("F") pass if __name__=="__main__": f=F() f.test() print(F.mro()) #类找下一个类的顺序
多态
#多态 继承的子类重写了同一父类的相同方法 #不同子类重写了父类的一个方法 if __name__=="__main__": class animal: def __init__(self,name): self.name=name def sleep(self): print("动物在睡觉!") class cat(animal): def __init__(self,name): super().__init__(name) # def sleep(self): # print("猫在睡觉") class dog(animal): def __init__(self, name): super().__init__(name) def sleep(self): print("狗在睡觉") cat("猫").sleep() dog("狗").sleep()
封装
#封装 #将类中的属性设置为私有,就叫封装 if __name__=="__main__": class animal: def __init__(self,name,type): self._name=name self._type=type #如何访问类的私有属性 print(animal("小黄","dog").__dict__.get("_name")) #获取对象字典get()取值
反射
#反射 #__getattr()__ 当前类获取不到就到父类去找数据或函数 #__setattr()__ 设置对象属性 #__delattr()__ 删除对象属性 if __name__=="__main__": class animal: def __init__(self,name): self.name=name class cat(animal): pass a=animal("tom") c=cat("ca") #获取对象属性 print("animal的name:",a.__getattribute__("name")) print("animal的name:",c.__getattribute__("name")) #__getattr()__ 当前类获取不到就到父类去找数据或函数 #添加数据属性 a.__setattr__("type","male") print(a.__getattribute__("type")) #添加函数属性 def sleep(): print("睡觉!..") a.__setattr__("sleep",sleep) a.__getattribute__("sleep")() #删除对象属性 print(a.__dict__) a.__delattr__("sleep") print(a.__dict__)
动态导入模块
# __import()__动态导入模块 time=__import__("time") #使用模板 print(time.time())
内置attr
# 内置attr # getattr() 获取对象属性 #setattr() #设置对象属性 #delattr() #删除对象属性 if __name__=="__main__": class animal: def __init__(self,name): self.name=name an=animal("小黄") #getattr() 类似 __getattr__() print(getattr(an,"name")) #setattr() 类似 __setattr()__ setattr(an,"type","male") print(getattr(an,"type")) #delattr() 类似 __delattr() print(an.__dict__) delattr(an,"type") print(an.__dict__)
__module__,__class__
from item import animal # __module__ 输出类所在的模块 # __class__ 输出当前类 a=animal() print(a.__module__) #输出模块 print(a.__class__) #输出类
__isinatance__,__issubclass__
#isinstance() 对象是否是某个类的实例 #issubclass() 某个类是否是另一个类的子类 if __name__=="__main__": class animal: def __init__(self,name): self.name=name an=animal("动物") # isinatance()对象是否是某个类的实例 print("an对象是否是animal类的实例:",isinstance(an,animal)) #issubclass() 某个类是否是另一个类的子类 class dog(animal): pass print("dog类是否是animal类的一个子类: ",issubclass(dog,animal))
item
# item 通过添加字典的方式添加属性时会触发item #getitem() 取值的时候会触发 #setitem() 为对象添加值时会触发 #delitem() 删除对象中的属性时会触发 class animal: def __getitem__(self, item): print("getitem") # self.__dict__.get(item) 从类的字典中取出值 return self.__dict__.get(item) def __setitem__(self, key, value): print("setItem") #self.__dict__.set(k,v) 为类的字典里添加属性 self.__dict__.__setitem__(key,value) def __delitem__(self, key): print("delitem") #self.__dict__.pop(k) 从类的字典里删除某个属性 self.__dict__.pop(key) if __name__=="__main__": an=animal() #添加值触发setitem() an["name"]="tom" print(an.__dict__) #{'name': 'tom'} #取值的时候会触发getitem() print(an["name"]) #tom #删除值时会触发delitem() del an["name"] print(an["name"]) # None
with 类 as
#with 类 as # with as 开始 触发 __enter__函数 # with as 结束 触发 __exit__函数 class Open: def __init__(self,name,modu): self.name=name self.__modu=modu def __enter__(self): print("enter...") def __exit__(self, exc_type, exc_val, exc_tb): print("exit...") print(exc_type) print(exc_val) print(exc_tb) with Open("a.txt","r") as f: print(f)
描述符
#描述符 代理其他类的的类叫做描述符 #__set__ 创建对象时触发 #__get__ 获取描述符的属性时触发 #__del__ #删除描述符属性时触发 #优先关系 # 类> # 数据描述符> 有set方法 # 对象> # 非数据描述符> 没有set方法 # getattr()方法 class Typehand: def __init__(self,name): self.name=name pass def __get__(self, instance, owner): print("__get__") #被代理类的对象 print(instance) #被代理的类 print(owner.__dict__) #取被代理对象的值 return instance.__dict__.get("name") def __set__(self, instance, value): print("__set__") #当前类 print(self) #被代理类的对象 print(instance) #被代理类实例化传过来的值 #print(value) #为被代理对象赋值 instance.__dict__.setdefault("position",value) pass def __delete__(self, instance): print("__delete__") #被代理类的对象 print(instance) #删除被代理对象的属性 instance.__dict__.pop("name") pass class city: position=Typehand("x") def __init__(self,name,position): self.name=name self.position=position #触发描述符set()方法 ci=city("上海","南方") #触发描述符set()方法 print(ci.position) #触发描述符del方法 print(ci.__dict__) del ci.position print(ci.__dict__)
__del__析构方法
# __del__ 对象被销毁时触发该函数 class a: def __init__(self): pass def __del__(self): print("__del__") a1=a()
类的装饰器
#类的装饰器 #定义 @ 与函数装饰器相同 #property class abc: def __init__(self,func): self.func=func def __get__(self, instance, owner): res=self.func(instance) setattr(instance,self.func,res) return res class person: def __init__(self,name,age): self.name=name self.age=age @property def sleep(self): print("%s 正在睡觉!"%self.name) per=person("小明",18) per.sleep per.sleep
迭代器协议
#迭代器协议 #满足 __iter__ 和 __next__叫做迭代器 class it: #__init__实例化对象 def __init__(self,num): self.num=num #通过__iter__方法使对象可迭代 def __iter__(self): return self # __next__ 迭代对象 def __next__(self): self.num += 1 if self.num==60: #触发终止 raise StopIteration else: return self.num #实例化对象 i=it(1) #开始迭代对象 #手动迭代遇到异常会报错 print(next(i)) #for 循环迭代 遇到异常只会终止,不会报错 for a in i: print(a)
内置函数
#内置函数 # __slots__ 取代__dict__用于存储类的属性 #优点:节省内存 #可以为属性赋值,但不可以添加属性 #可以取值 # class animal: __slots__ = ["name","age"] an=animal() #赋值 an.name="tom" print(an.name) #删除值 del an.name #删除属性 an.__slots__.remove("name") print(an.__slots__) #['age'] #__call__ #调用函数的方式调用对象时会触发 class animal: def __call__(self, *args, **kwargs): print("call被调用") print(*args) print(**kwargs) an=animal() #调用call函数 an(1,2,3,4,{"x":"1","y":"2"}) #__doc__ 注释 获取每个类的注释,每个类的注释不可以被其它类调用 class animal1: "这是animal1类的注释" # __doc__获取类的注释 print(animal1.__doc__) #__getattribute__ 获取类的属性值时会触发,如果出现AttributeError异常,会调用__getattr__函数 #raise Error 自定义异常 class animal2: def __init__(self,name): self.name=name def __getattr__(self, item): print("__getattr__") def __getattribute__(self, item): print("__getattribute__") #自定义异常 raise AttributeError a2=animal2("猫") print(a2.name) #__getattribute__ __getattr__ None #__str__ 用于将类输出为字符串 # __repr__ #类中没有定义__str__会调用__repr__函数 # __format__ class animal3: def __init__(self,name): self.name=name def __str__(self): return "这是str" def __repr__(self): return "这是repr" a3=animal3("x") #输出对象 print(a3) #这是str #__format__ tim={"y-m-d":"2016-12-12", "m-d-y":"12-12-2016", "ymd":"20161212"} class time1: def __init__(self): pass def __format__(self, format_spec): if not format_spec: return tim["ymd"] return tim[format_spec] t=time1() print(format(t,'y-m-d'))
元类
# type 元类 元类可以操纵生成类 #继承元类type,使其拥有元类的特性 class type1(type): #__call__创建创造类的对象 def __call__(self, *args, **kwargs): print("__call__") print(self, *args, **kwargs) obj=object.__new__(self) self.__init__(obj,*args,**kwargs) return obj #定义元类为type1 class cat(metaclass=type1): def __init__(self,name="小猫"): self.name=name def sleep(self): print("%s 睡觉!"%self.name) #实例化类触发__new__方法 ca=cat("小狗") #测试对象的函数 ca.sleep()