python-面向对象
Posted allenwoo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python-面向对象相关的知识,希望对你有一定的参考价值。
面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
面向对象的设计思想是抽象出Class,根据Class创建Instance
面向对象的抽象程度又比函数要高,因为一个Class既包含数据,又包含操作数据的方法。
类名通常是大写开头的单词,采用驼峰式
在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
这样就确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可
以通过_Student__name来访问__name变量:
但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名。
在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用
__name__、__score__这样的变量名。
有些时候,你会看到以一个下划线开头的实例变量名,比如_name,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
python多继承-新式类、经典类
比如父类中有一个run方法,子类也定义了run方法,父类对象.run会调用父类的run,子类对象.run则调用子类的run,这就是多态
一个子类对象的类型既是子类,也是父类,这也是多态
静态语言与动态语言的区别:比如定义一个函数,传入对象,调用对象的run方法
对于静态语言(例如Java)来说,参数设置需要指定类型,传入的对象必须是指定类型或者子类,否则调用失败
而对于动态语言来说,传入的对象没有任何类型的限制,只需要这个对象也有run方法即可
这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
type(obj)表示obj是有谁创建的: 当obj为实例化对象时,结果为类,因为obj是由该类创建的;当obj为类时,结果为type,因为类是有type创建的
isinstance(obj,class)则是判断obj是什么类型:当obj为实例化对象时,结果为类,因为obj的类型是该类; 当obj为类时,结果为object,因为它的类型是object
对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数。
实例属性属于各个实例所有,互不干扰;
类属性属于类所有,所有实例共享一个属性;
不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误。
类可以起到模板的作用,通过定义一个特殊的__init__方法,在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。 和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。 方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据; class foo:#定义类 staticword = ‘staticword‘#静态字段/类属性,类/对象都可以访问 __nationl = ‘china‘#静态私有字段,可以在类内部用类名.xxxx/对象.xxxx访问,外部访问应该通过方法间接访问 def __init__(self,name,age):#类的构造方法,创建对象时自动执行 self.name = name#定义普通字段/普通变量,通过对象来访问 self.__age = age#私有字段/私有变量,可以在类内部通过对象访问,外部无法直接进行访问 #父类的私有字段,无法继承,子类的方法无法直接调用父类的私有字段 def f1(self):#定义普通方法,对象.xxxx()来访问/类名.f1(对象)也可以访问 print(‘执行普通方法‘) @staticmethod def f2():#定义静态方法,类名.xxxx()/对象.xxxx()都可以访问 print(‘执行静态方法‘) @classmethod def f3(cls):#定义类方法,类名.xxxx()/对象.xxxx()都可以访问 print(‘执行类方法‘) @property#不伦不类1 def f4(self):#对象.xxxx直接访问/但类名.xxxx访问不成功,也不报错? print(‘property‘) return 1 @f4.setter#不伦不类1 def f5(self,xxx):#对象.f5 = 123(任意数值),此处方法名和定义为f4 print(‘perr.setter‘) @f4.deleter#不伦不类1 def f6(self):# del 对象.f6,此处方法名和定义为f4 print(‘perr.deleter‘) def wordtest(self): print(self.__age)#间接访问私有字段 print(foo.__nationl)#间接访问私有字段 return foo.__nationl#间接访问私有字段 def __call__(self, *args, **kwargs):#对象()/类名()() 自动执行 print(‘__call__‘) def __int__(self):#int(对象) 自动执行,返回值赋值给int对象 print(‘__int__‘)#貌似并不是赋值给对象,因为进行int(对象)操作之后,单独打印对象,显示的还是‘s`123‘ return 1233#必须为数字,否则报错, def __str__(self):#str(对象) 自动执行 print(‘__str__‘)#print(对象)也会自动调用对象的str方法 #print(对象) ==print(str(对象)) return ‘s`123‘ def __add__(self, other):#对象+对象 定义了该方法后,进行+时自动执行第一个对象的该方法,把第二个对象当参数传入,返回自定义的值 return self.name+other.name def __del__(self):#在对象被销毁时,自动执行该方法 print(‘析构方法‘)#没什么用,知道一下 #对象.__dict__ 将对象中封装的所有内容通过字典的形式返回 #类名.__dict__ 将类中的所有内容通过字典的形式返回,包括一个备注(‘‘‘ ‘‘‘)也会当做类成员,成为一对键值对 def __getitem__(self, item):#对象[9] 自动执行该方法,将9作为参数传递给item #在python3中,通过类似列表切片的方式 list[1:6:2]还是执行__getitem__;但在python2中不是 if type(item) == slice: print(‘对象为slice,切片处理‘) print(item.start,111) print(item.stop,222) print(item.step,333) else: print(‘对象为非slice,索引处理‘) # return item+10 def __setitem__(self, key, value):#对象[9] = 123;自动执行该方法,不需要设置return self.key=value print(‘__setitem_____‘) def __delitem__(self, key): print(‘delete%s‘%key)#del 对象[9];自动执行该方法,不需要设置return def __iter__(self): return iter([1,2,3]) #如果类中有__iter__方法,那么该类产生的对象为---可迭代对象 #对象.__iter__()的返回值:迭代器 #for循环的对象是一个迭代器时,直接执行next #for循环的对象是一个可迭代对象时,执行对象.__iter__(),返回一个迭代器,再对迭代器执行next fo = foo(‘allen‘,30) for i in fo:#1、若fo为迭代器,直接进行迭代;2、若fo为可迭代对象,执行__iter__方法,取返回值 print(i,112233)
class F: def f1(self): print(‘111‘) class S(F):#继承F def f2(self): print("222") def f1(self):#若不想继承父类的方法,只需要自己内部也创建一个相应的方法 super(S,self).f1()#若想同时执行父类的同名函数,可以这样 print(‘333‘)#super(S,self)等同于父类 #F.f1()#另一种调用父类方法的写法 obj = S()#2个动作,1.创建对象,2.执行__init__进行属性赋值 obj.f1() obj.f2() S.f2(obj)#调用方法的另一种写法 面向对象三大特性之一:封装 面向对象三大特性之二:继承 1、继承 2、重写 防止执行父类中的方法#修改父类的方法 3、self永远是执行该方法的调用者 4、super(子类, self).父类中的方法(...) 父类名.父类中的方法(self,...) 5、Python中支持多继承#java不能多继承 a. 左侧优先 b. 一条道走到黑 c. 同一个根时,根最后执行 面向对象三大特性之三:多态 ====> 原生多态 类成员: # 字段 - 普通字段,保存在对象中,只能通过对象访问 - 静态字段,保存在类中, 可以通过对象访问;也可以通过类访问 # 方法 - 普通方法,保存在类中,由对象来调用,self=》对象 - 静态方法,保存在类中,由类直接调用 - 类方法,保存在类中,由类直接调用,cls=》当前类 # 属性,特性 - 不伦不类
以上是关于python-面向对象的主要内容,如果未能解决你的问题,请参考以下文章