python的面向对象
Python从设计之初就已经是一门面向对象的语言。
一 从创建一个类开始
class human: def xx(self): pass def printf(self): print("创建类") def hello(self,name): print("My name is %s" %name) obj =human() obj.printf() obj.hello("TheDa")
pass是python中的常用的空语句。
类中定义的方法的第一个参数必定是self
类成员的定义?
class stu: number=0 def __init__(self,name,id): self.name=name; self.id=id stu.number+=1 def display(self): print("My name is{},My id is{}".format(self.name,self.id)) obj=stu("TheDa",30142017) obj.display() print(stu.number) obj1=stu("TheDa1",30152017) obj1.display() print(stu.number)
可以看出number类似于java中的静态变量,可以用于储存类共享的变量信息。访问时使用类名.变量来访问。
python的成员变量需要在__init__()构造函数中定义
不是,所有在类中,def模块里的,运行过的self.变量名,都会成为类里的实例变量
代码如下
class Member(): num=0 #类变量,可以直接用类调用,或用实例对象调用 def __init__(self,x,y): self.x=x #实例变量(成员变量),需要它是在类的构造函数内以self.开头来定义的 self.y=y self.fuc(self.x,self.y) def add(self): total=2 #局部变量 self.vara=3 # 虽是以self.给出,但并没有在构造函数中进行初始化 self.varb=4 fina=(self.x+self.y)*total return fina def fuc(self,a,b): self.varc=a #成员变量,他们在成员函数fuc()中定义,但是在构造函数中调用了fuc()函数 self.vard=b obj=Member(1,1) print(obj.varc)#1 obj.add()#若这句话注释了就会出错 print(obj.vara)#3 obj.vara+=1 print(obj.vara)#4
二 类成员的访问权限与python中的单下划线和双下划线
https://blog.csdn.net/hlang8160/article/details/79013145
三 python的类变量和成员变量之间的关系
class TestClass(object): val1 = 100 def __init__(self): self.val2 = 200 def fcn(self,val = 400): val3 = 300 self.val4 = val self.val5 = 500 inst1 = TestClass() inst2 = TestClass() print (TestClass.val1) # 100 print (inst1.val1) # 100 inst1.val1 = 1000 print (inst1.val1) # 1000 print (TestClass.val1) # 100 TestClass.val1 =2000 print (inst1.val1) # 1000 print (TestClass.val1) # 2000 print (inst2.val1) # 2000 inst3 = TestClass() print (inst3.val1) # 2000
可以从中总结出类,类的实例对象中类变量的内存管理。
首先,类的类变量是在内存中得到保存的。只能通过类名.类变量名来修改。
而类的各个实例对象,一开始并不知道类变量是什么。直到实例对象第一次使用类变量的时候,就会从内存中类中
的类变量copy一个值过来。然后之后这个类实例对象中的类变量如何改变都不会对其他地方产生任何影响。
那么这个用self访问类变量呢?
class father: count = 0 l= [] def funa(self): self.count += 1 self.l.append('a') father.count += 3 father.l.append("b") if __name__ == "__main__": fa = father() fa.funa() print(fa.count)#1 print(fa.l) #['a', 'b'] print(father.count) #3 print(father.l) #['a', 'b'] fb = father() fb.funa() print(fb.count) #4 print(fa.l) #['a', 'b', 'a', 'b'] print(father.count) #6 print(father.l) #['a', 'b', 'a', 'b']
这里的count还是符合之前的想法的。
但是为什么这个list这么奇怪?
https://blog.csdn.net/xcd1997/article/details/81222781这里说了这个问题。
只能说list比较奇怪吧。
class List(object): list=[] def __init__(self,list=[]): self.list=list list1=List() list1.list.append('12') list2=List() print(list2.list)#['12']
用id(test1.List) 和id(test2.List) 可以发现,两个的id值一样。
那么为什么会这样呢?
四 python的类的继承
单继承
class people: name='' age=0 #定义私有属性 __weight=0 def __init__(self,n,a,w): self.name=n self.age=a self.__weight=w def display(self): print("%s 说: 我 %d 岁。" %(self.name,self.age)) class stu(people): grade=0 def __init__(self,n,a,w,g): people.__init__(self,n,a,w) self.grade=g #覆盖父类的方法 def display(self): print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade)) obj=stu("TheDa",20,110,15) obj.display()
多继承
同java,不推荐使用。
当以一个子类有多个直接父类时,该子类会继承得到所有父类的方法,但是如果其中有多个父类包含同名方法会发生什么?此时排在前面的父类中的方法会“遮蔽”后面父类中的方法。
方法重写
五 python的类专有方法和运算符重载
__init__ : 构造函数,在生成对象时调用
__del__ : 析构函数,释放对象时使用
__repr__ : 打印,转换
__setitem__ : 按照索引赋值
__getitem__: 按照索引获取值
__len__: 获得长度
__cmp__: 比较运算
__call__: 函数调用
__add__: 加运算
__sub__: 减运算
__mul__: 乘运算
__truediv__: 除运算
__mod__: 求余运算
__pow__: 乘方
__str__:如下貌似是输出定义
重载加法运算如下
class Vector: def __init__(self, a, b): self.a = a self.b = b def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self,other): return Vector(self.a + other.a, self.b + other.b) v1 = Vector(2,10) v2 = Vector(5,-2) print (v1 + v2)