9 面向对象(类) --python
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了9 面向对象(类) --python相关的知识,希望对你有一定的参考价值。
类是一系列对象共有的特征(变量的定义)与技能(函数的定义)的结合体
类中一些常见成员
1. __doc__ 表示类的描述信息 2. __module__ 和 __class__ __module__ 表示当前操作的对象在那个模块 __class__ 表示当前操作的对象的类是什么 3. __init__ 构造方法,通过类创建对象时,自动触发执行。 4. __del__ 析构方法,当对象在内存中被释放时,自动触发执行。 注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。 5. __call__ 对象后面加括号,触发执行。 注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()() 6. __dict__ 类或对象中的所有成员 7. __str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。 8、__getitem__、__setitem__、__delitem__ 用于索引操作,如字典。以上分别表示获取、设置、删除数据 9、__getslice__、__setslice__、__delslice__ 该三个方法用于分片操作,如:列表 10. __iter__ 用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__
定义和实例化
class Chinese: country=‘China‘ # Chinese.__init__(p1,‘egon‘,‘18‘,‘male‘) def __init__(self,name,age,sex): #p1.Name=name p1.Age=age p1.Sex=sex self.Name=name self.Age=age self.Sex=sex def talk(self): print(‘%s is talking‘ %self.Name) #属性的引用 # print(Chinese.country) # print(Chinese.talk) # Chinese.talk(1) # Chinese.x=1 # print(Chinese.x) # Chinese.country=123123111 # print(Chinese.country) #实例化 class Chinese: country = ‘China‘ # Chinese.__init__(p1,‘egon‘,‘18‘,‘male‘) def __init__(self, name, age, sex): # p1.Name=name;p1.Age=age,p1.Sex=sex self.Name = name self.Age = age self.Sex = sex def talk(self): print(‘%s is talking‘ %self.Name) # p1=Chinese(‘egon‘,‘18‘,‘male‘) #Chinese.__init__(p1,‘egon‘,‘18‘,‘male‘) # p2=Chinese(‘alex‘,‘9000‘,‘female‘) #Chinese.__init__(p1,‘egon‘,‘18‘,‘male‘) #对象的使用:只有一种,就是属性引用 # print(p1.Name) # print(p1.Age) # print(p1.Sex) # print(p2.Name) # print(p1.country) # print(p2.country) # p1.talk() # p2.talk() country = ‘aaaaaaaaaa‘ class Chinese: country = ‘China‘ def __init__(self, name, age, sex): # self.country=123123123123123123 self.Name = name self.Age = age self.Sex = sex def talk(self): print(‘%s is talking‘ %self.Name) #类名称空间 # print(Chinese.__dict__) #对象的空间 p1=Chinese(‘egon‘,‘12‘,‘male‘) #Chinese.__init__(p1,‘egon‘,‘18‘,‘male‘) p2=Chinese(‘alex‘,‘9000‘,‘female‘) # p2=Chinese() # print(p1) #对象的使用:只有一种,就是属性引用 # print(p1.country) # print(p2.country) # print(p1.Name) # print(p1.Age) # print(p1.Sex) # print(p1.__dict__) # print(p1.Age) #p1.__dict__[‘Age‘] # print(p1.country,id(p1.country)) # print(p2.country,id(p2.country)) # print(Chinese.talk) # print(p1.talk) # p1.talk() #Chines.talk(p1) # print(p2.talk) # p2.talk()#chinese.talk(p2) print(type(p1))
继承
#什么是继承:一种创建新类的方式 # class ParentClass1: # pass # class ParentClass2: # pass # # class SubClass1(ParentClass1): # pass # class SubClass2(ParentClass1,ParentClass2): # pass # # print(SubClass1.__bases__) # print(SubClass2.__bases__) # # #python2中 类分为:新式类与经典类 # class Foo(object): #新式类 # pass # # class Bar: #经典类 # pass # #python3中 类全部都是新式类 # # class Foo(): #新式类 # pass # # # print(Foo.__bases__) #寻找继承关系 #继承的好处一:减少冗余代码 #在子类定义新的属性,覆盖掉父类的属性,称为派生 # class Animal: # def __init__(self,name,age,sex): # self.name=name # self.age=age # self.sex=sex # # def eat(self): # print(‘eating‘) # # def talk(self): # print(‘%s 正在叫‘ %self.name) # # class People(Animal): # def __init__(self,name,age,sex,education): # Animal.__init__(self,name,age,sex) # self.education=education # def talk(self): # print(‘%s say hello‘ %self.name) # # class Pig(Animal): # pass # # class Dog(Animal): # pass # # peo1=People(‘alex‘,18,‘male‘,‘no bibi‘) #People.__init__ # # pig1=Pig(‘wupeiqi‘,20,‘female‘) # # dog1=Dog(‘yuanhao‘,30,‘male‘) # print(isinstance(peo1,People)) # print(isinstance(pig1,Pig)) # print(isinstance(dog1,Dog)) # print(isinstance(peo1,Animal)) # peo1.talk() # pig1.talk() # dog1.talk() # print(peo1.education) #下列代码的结果是 # class Parent: # def foo(self): # print(‘Parent.foo‘) # self.bar() #s.bar() # # def bar(self): # print(‘Parent.bar‘) # # class Sub(Parent): # def bar(self): # print(‘child.bar‘) # # # s=Sub() # s.foo() #优先从对象本身找,找不到再从父类去找 #继承反映的是一种什么是什么的关系 #组合也可以解决代码冗余问题,但是组合反映是一种什么有什么的关系 # class Date: # def __init__(self,year,mon,day): # self.year=year # self.mon=mon # self.day=day # # def tell(self): # print(‘%s-%s-%s‘ %(self.year,self.mon,self.day)) # # class People: # def __init__(self,name,age,sex): # self.name=name # self.age=age # self.sex=sex # # class Teacher(People): # def __init__(self, name, age, sex,salary,year,mon,day): # # People.__init__(self,name,age,sex) # # self.name=name # self.age=age # self.sex=sex # self.salary=salary # self.birth=Date(year,mon,day) # # # t=Teacher(‘egon‘,18,‘male‘,3000,1999,11,9) # # t.birth.tell() # # class Student(People): # pass # class File:#定义接口Interface类来模仿接口的概念,python中压根就没有interface关键字来定义一个接口。 # def read(self): #定接口函数read # raise TypeError(‘类型错误‘) # # def write(self): #定义接口函数write # raise TypeError(‘类型错误‘) # # # class Txt(File): #文本,具体实现read和write # def read(self): # print(‘文本数据的读取方法‘) # # def write(self): # print(‘文本数据的读取方法‘) # # class Sata(File): #磁盘,具体实现read和write # def read(self): # print(‘硬盘数据的读取方法‘) # # def write(self): # print(‘硬盘数据的读取方法‘) # # class Process(File): # # def read(self): # # print(‘进程数据的读取方法‘) # # # # def write(self): # # print(‘进程数据的读取方法‘) # def xie(self): # pass # # def du(self): # pass # p=Process() # p.read() # t=Txt() # p=Process() # d=Sata() # # print(isinstance(t,File)) # print(isinstance(p,File)) # print(isinstance(d,File)) # # # # t.read() # p.read() # d.read() #抽象类 # import abc # class File(metaclass=abc.ABCMeta):#定义接口Interface类来模仿接口的概念,python中压根就没有interface关键字来定义一个接口。 # @abc.abstractmethod # def read(self): #定接口函数read # pass # # @abc.abstractmethod # def write(self): #定义接口函数write # pass # # class Process(File): # def read(self): # # print(‘进程数据的读取方法‘) # pass # def write(self): # print(‘进程数据的读取方法‘) # # # def xie(self): # # pass # # # # def du(self): # # pass # p=Process() # p.read() #继承的实现原理 # class E: # # def test(self): # # print(‘from E‘) # pass # # class A(E): # # def test(self): # # print(‘from A‘) # pass # class D: # # def test(self): # # print(‘from D‘) # pass # class B(D): # # def test(self): # # print(‘from B‘) # pass # class C: # def test(self): # print(‘from C‘) # pass # # class F(A,B,C): # # def test(self): # # print(‘from F‘) # pass # # # f=F() # f.test() #继承类查找顺序依次为F(类本身)、A、E、B、D、C 具体继承图 可见附件继承1 # class A: # def test(self): # print(‘from A‘) # pass # # class B(A): # # def test(self): # # print(‘from B‘) # pass # # class C(A): # # def test(self): # # print(‘from C‘) # pass # # class D(B): # # def test(self): # # print(‘from D‘) # pass # # class E(C): # # def test(self): # # print(‘from E‘) # pass # # # class F(D,E): # # def test(self): # # print(‘from F‘) # pass # # f=F() # f.test() #继承类的查找顺序依次是F(本身)、D、B、E、C、A 具体继承图 可见附件继承图2 # class A: # def test(self): # print(‘from A‘) # pass # # class B(A): # # def test(self): # # print(‘from B‘) # pass # # class C(A): # # def test(self): # # print(‘from C‘) # pass # # class D(B): # # def test(self): # # print(‘from D‘) # pass # # class E(C): # # def test(self): # # print(‘from E‘) # pass # # class H(A): # # def test(self): # # print(‘from H‘) # pass # # class F(D,E,H): # # def test(self): # # print(‘from F‘) # pass # # f=F() # f.test() #继承类的查找顺序依次是F(本身)、D、B、E、C、H、A 具体继承图 可见附件继承图3 # (遵从原则广度,再从深度,相同广度下按ASCII码顺序查找 #新式类:广度优先,F->D->B->E->C->H->A class Foo(): def test(self): print(‘from foo.test‘) class Foo2(): def test(self): print(‘from foo2.test‘) class Bar(Foo,Foo2): def test(self): # Foo.test(self) # super(Bar, self).test() #在python2中 调用父类的特征 super().test() print(‘bar‘) b=Bar() b.test() print(Bar.mro()) #调用对象顺序,依次为Bar(本身),Foo, Foo2
多态和多态性
#多态 #同一种事物的多种形态 class Animal: def talk(self): print(‘正在叫‘) class People(Animal): def talk(self): print(‘say hello‘) class Pig(Animal): def talk(self): print(‘哼哼哼‘) class Dog(Animal): def talk(self): print(‘汪汪汪‘) class Cat(Animal): def talk(self): print(‘喵喵喵‘) peo1=People() pig1=Pig() dog1=Dog() cat1=Cat() #多态性 指的是具有不同功能的函数可以使用相同的函数名 # peo1.talk() # pig1.talk() # dog1.talk() # cat1.talk() def func(obj): obj.talk() func(peo1) func(pig1) func(dog1) func(cat1)
封装
#封装类型 :主要有 数据封装、方法封装 #封装的原因: # 1 保护隐私 # 2 隔离复杂度 # class Foo: # __x=2 # x=1 # def test(self): # print(‘from test‘) # # print(Foo.x) # # print(Foo.__x) # print(Foo.__dict__) # print(Foo._Foo__x) # class People: # def __init__(self,name,age,sex): # __country=‘china‘ # self.__name=name # self.__age=age # self.__sex=sex # # def tell_info(self): # print(‘人的名字是:%s,人的性别是:%s,人的年龄是:%s‘ %( # self.__name, # self.__age, # self.__sex # )) # # p=People(‘alex‘,18,‘male‘) # print(p.__dict__) # p.tell_info() # # # print(p.__name) # # p.__salary=3000 # print(p.__dict__) # class Parent(): # def foo(self): # print(‘from parent.foo‘) # # self.bar() # # self._bar() #self._Parent__bar() # # def __bar(self): # Parent__bar # print(‘from parent.bar‘) # # # class Sub(Parent): # # def bar(self): # # print(‘from Sub.bar‘) # # pass # # # s=Sub() # s.foo() # # # s.bar() # # s._Parent__bar() # s._Parent__bar() # class People: # def __init__(self,name,age): # self.__name=name # self.__age=age # # def tell_info(self): # print(‘人的名字是:%s,人的年龄是:%s‘ %( # self.__name, # self.__age # # self.__sex # )) # # def set_info(self,x,y): # if not isinstance(x,str): #类型检查 # raise TypeError(‘名字必须是字符串类型‘) # if not isinstance(y,int): # raise TypeError(‘年龄必须是整形‘) # self.__name=x # self.__age=y # # p=People(‘egon‘,1000) # p.tell_info() # # p.set_info(‘alex‘,2000) # p.tell_info() # property # class Foo: # # @property # def test(self): # print(‘from foo‘) # # # test=property(test) # # # f=Foo() # f.test() # class People: # def __init__(self,name,weight,height): # self.name=name # self.weight=weight # self.height=height # # @property # def bmi(self): # return self.weight/(self.height ** 2) # # p=People(‘egon‘,75,1.8) # print(p.bmi) # class People: # def __init__(self,name): # self.__name=name # # @property # def name(self): # return self.__name # # p=People(‘egon‘) # # print(p.name) # class People: # def __init__(self,name,permmission=False): # self.__name=name # self.permmission=permmission # @property # def name(self): # return self.__name # # @name.setter # def name(self,value): # if not isinstance(value,str): # raise TypeError(‘名字必须是字符串类型‘) # self.__name=value # # @name.deleter # def name(self): # if not self.permmission: # raise PermissionError(‘不允许的操作‘) # del self.__name # # p=People(‘egon‘) # # # print(p.name) # # # # p.name=‘egon666‘ # # print(p.name) # # # # p.name=35357 # p.permmission=True # del p.name class People: def __init__(self,name,permmission=False): self.__name=name self.permmission=permmission def get_name(self): return self.__name def set_name(self,value): if not isinstance(value,str): raise TypeError(‘名字必须是字符串类型‘) self.__name=value def del_name(self): if not self.permmission: raise PermissionError(‘不允许的操作‘) del self.__name name=property(get_name,set_name,del_name) p=People(‘egon‘) # print(p.name) # # p.name=‘egon666‘ # print(p.name) # # p.name=35357 p.permmission=True del p.name
了解面向对象中的反射
#python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射) # class Foo: # pass # # class Bar(Foo): # pass # # print(issubclass(Bar,Foo)) #判断是否是子类 #反射 class Chinese: country=‘China‘ def __init__(self,name,age): self.name=name self.age=age # print(Chinese.country) # 实质 Chinese.__dict__[‘country‘] p=Chinese(‘egon‘,18) # print(p.name) # p.__dict__[‘name‘] # print(p.age) # p.__dict__[‘age‘] # print(p.__dict__[‘name‘]) #属性都必须是字符串格式 #判断object中有没有一个name字符串对应的方法或属性 # hasattr(p,‘name‘) # print(hasattr(p,‘name‘)) # print(hasattr(p,‘age‘)) # print(hasattr(p,‘__init__‘)) # print(hasattr(Chinese,‘country‘)) #setattr 设置属性 # p.x=1 # print(p.__dict__) # setattr(p,‘x‘,123123) # print(p.__dict__) # print(p.x) # print(getattr(p,‘x‘,‘not exist‘)) # print(getattr(p,‘name‘)) # setattr(p,‘x‘,111) # if hasattr(p,‘x‘): # res=getattr(p,‘x‘) # print(res) # delattr 删除属性 # print(Chinese.country) delattr(Chinese,‘country‘) # print(Chinese.country) # print(p.country) # p1=Chinese(‘aaa‘,18) # print(p1.country) # import sys # m=sys.modules[__name__] # print(m) # # if hasattr(m,‘Chinese‘): # res=getattr(m,‘Chinese‘) # print(res) # # obj=res(‘egon‘,18) # print(obj.name) p.name # p.__dict__[‘name‘] getattr(p,‘name‘) # p.__dict__[‘name‘]
以上是关于9 面向对象(类) --python的主要内容,如果未能解决你的问题,请参考以下文章
Python全栈--9.1--面向对象进阶-super 类对象成员--类属性- 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理