一、静态属性
静态属性说的就是数据属性
1、定义一个房间的类,求下这个房间的面积
class Room: def __init__(self,name,ower,width,length,heigh): self.Name=name self.Ower=ower self.Width=width self.Length=length self.Heigh=heigh r1=Room("厕所","北爷",2,2,20000)#实例化出来一个实例r1,实例化的过程就是执行__init__ print(r1.__dict__)#查看下r1这个实例的属性字典 print("%s 住的%s 总面积是%s平米的地下室" %(r1.Ower,r1.Name,r1.Width*r1.Length))#进行字符串拼接 C:\python35\python3.exe D:/pyproject/day25/静态属性.py {'Length': 2, 'Ower': '北爷', 'Name': '厕所', 'Heigh': 20000, 'Width': 2} 北爷 住的厕所 总面积是4平米的地下室
2、又来了一个人,又要求下他的房子的面积
class Room: def __init__(self,name,ower,width,length,heigh): self.Name=name self.Ower=ower self.Width=width self.Length=length self.Heigh=heigh r1=Room("厕所","北爷",2,2,20000)#实例化出来一个实例r1,实例化的过程就是执行__init__ r2=Room("北京","喵爷",20,60,20000) # print(r1.__dict__)#查看下r1这个实例的属性字典 print("%s 住的%s 总面积是%s平米的地下室" %(r1.Ower,r1.Name,r1.Width*r1.Length))#进行字符串拼接 print("%s 住的%s 总面积是%s平米的地下室" %(r2.Ower,r2.Name,r2.Width*r1.Length)) C:\python35\python3.exe D:/pyproject/day25/静态属性.py 北爷 住的厕所 总面积是4平米的地下室 喵爷 住的北京 总面积是40平米的地下室
3、我们这样做肯定是不行的。这相当于是在外面完成的这件事情,而且很麻烦,应该把这个计算面积弄成一个函数
class Room: def __init__(self,name,ower,width,length,heigh): self.Name=name self.Ower=ower self.Width=width self.Length=length self.Heigh=heigh def cal_area(self): print("%s 住的%s 总面积是%s平米的地下室" %(self.Ower, self.Name, self.Width * self.Length)) r1=Room("厕所","北爷",2,2,20000)#实例化出来一个实例r1,实例化的过程就是执行__init__ r2=Room("北京","喵爷",20,60,20000)#实例化第二个实例 r1.cal_area()#实例调用类的函数属性会自动传实例本身作为参数 r2.cal_area()#实例调用类的函数属性会自动传实例本身作为参数 C:\python35\python3.exe D:/pyproject/day25/静态属性.py 北爷 住的厕所 总面积是4平米的地下室 喵爷 住的北京 总面积是1200平米的地下室
4、property装饰器
class Room: def __init__(self,name,ower,width,length,heigh): self.Name=name self.Ower=ower self.Width=width self.Length=length self.Heigh=heigh @property #把一个方法变成一个数据属性 def cal_area(self): print("%s 住的%s 总面积是%s平米的地下室" %(self.Ower, self.Name, self.Width * self.Length)) r1=Room("厕所","北爷",2,2,20000)#实例化出来一个实例r1,实例化的过程就是执行__init__ r2=Room("北京","喵爷",20,60,20000) r1.cal_area#用了property这个装饰器之后,实例在调用函数属性就等于调用数据属性,不用加()就可以调用 r2.cal_area C:\python35\python3.exe D:/pyproject/day25/静态属性.py 北爷 住的厕所 总面积是4平米的地下室 喵爷 住的北京 总面积是1200平米的地下室
5、这样还不行。因为正常的数据属性直接运行是没有返回值的
6、现在改为了直接return一个返回值,现在用起来的效果就是跟调用数据属性是一模一样的了,property这个装饰器就是把类的函数属性变为数据属性,也就是封装成了数据属性
class Room: def __init__(self,name,ower,width,length,heigh): self.Name=name self.Ower=ower self.Width=width self.Length=length self.Heigh=heigh @property #把一个方法变成一个数据属性 def cal_area(self): # print("%s 住的%s 总面积是%s平米的地下室" %(self.Ower, self.Name, self.Width * self.Length)) # return (self.Width * self.Length) return "%s 住的%s 总面积是%s平米的地下室" % (self.Ower, self.Name, self.Width * self.Length) r1=Room("厕所","北爷",2,2,20000)#实例化出来一个实例r1,实例化的过程就是执行__init__ r2=Room("北京","喵爷",20,60,20000) print(r1.cal_area)#用了property这个装饰器之后,实例在调用函数属性就等于调用数据属性,不用加()就可以调用 print(r2.cal_area) print(r1.Name)#调用r1这个实例的数据属性 print(r2.Name)#调用r2这个实例的数据属性 C:\python35\python3.exe D:/pyproject/day25/静态属性.py 北爷 住的厕所 总面积是4平米的地下室 喵爷 住的北京 总面积是1200平米的地下室 厕所 北京
7、算是完美了,我们在增加一个计算体积的,当做是练习一下
class Room: def __init__(self,name,ower,width,length,heigh): self.Name=name self.Ower=ower self.Width=width self.Length=length self.Heigh=heigh @property #把一个方法变成一个数据属性 def cal_area(self): # print("%s 住的%s 总面积是%s平米的地下室" %(self.Ower, self.Name, self.Width * self.Length)) # return (self.Width * self.Length) return "%s 住的%s 总面积是%s平米的地下室" % (self.Ower, self.Name, self.Width * self.Length) @property def cal_tiji(self): return "%s 住的%s 总体积是%s平米的地下室" % (self.Ower, self.Name, self.Width * self.Length * self.Heigh) r1=Room("厕所","北爷",2,2,20000)#实例化出来一个实例r1,实例化的过程就是执行__init__ r2=Room("北京","喵爷",20,60,20000) r3=Room("西安","修电脑",20,60,20000) print(r1.cal_area)#用了property这个装饰器之后,实例在调用函数属性就等于调用数据属性,不用加()就可以调用 print(r2.cal_area) print(r3.cal_tiji) C:\python35\python3.exe D:/pyproject/day25/静态属性.py 北爷 住的厕所 总面积是4平米的地下室 喵爷 住的北京 总面积是1200平米的地下室 修电脑 住的西安 总体积是24000000平米的地下室
二、类方法
1、类是怎么调用自己的数据属性呢
class Room: tag=1#定义一个类的数据属性 def __init__(self,name,ower,width,length,heigh): self.Name=name self.Ower=ower self.Width=width self.Length=length self.Heigh=heigh @property #把一个方法变成一个数据属性 def cal_area(self): return "%s 住的%s 总面积是%s平米的地下室" % (self.Ower, self.Name, self.Width * self.Length) @property def cal_tiji(self): return "%s 住的%s 总体积是%s平米的地下室" % (self.Ower, self.Name, self.Width * self.Length * self.Heigh) print(Room.tag) C:\python35\python3.exe D:/pyproject/day25/静态属性.py 1
2、由于self把类和实例绑定到一起了,所以我们的折中方案就是先生成一个实例,然后在用类去调用方法,把实例手动穿进去
class Room: tag=1#定义一个类的数据属性 def __init__(self,name,ower,width,length,heigh): self.Name=name self.Ower=ower self.Width=width self.Length=length self.Heigh=heigh def tell_info(self): print("---->",self.tag) r1 = Room("厕所", "北爷", 2, 2, 20000) Room.tell_info(r1)#类调用类的函数属性的时候需要手动传实例本身 C:\python35\python3.exe D:/pyproject/day25/静态属性.py 1 ----> 1
3、但是我如果只想执行类的方法,不想跟任何实例有捆绑,该怎么做呢,python给我们提供了classmethod这个装饰器,只要用了这个方法, 就表示这个装饰器下面的方法是专门给类用的
这个方法就是只是类在调用类的方法,跟实例没关系,只要加了classmethod就只能供类调用
class Room: tag=1#定义一个类的数据属性 def __init__(self,name,ower,width,length,heigh): self.Name=name self.Ower=ower self.Width=width self.Length=length self.Heigh=heigh @classmethod#这个装饰器是专门供类使用的方法 def tell_info(cls):#cls代表类本身 print(cls) print("---",cls.tag)#等价于Room.tag Room.tell_info()#会自动把类本身传给cls C:\python35\python3.exe D:/pyproject/day25/静态属性.py <class '__main__.Room'> --- 1
三、静态方法 叫类的工具包,不跟类绑定也不跟实例绑定
class Room: tag=1#定义一个类的数据属性 def __init__(self,name,ower,width,length,heigh): self.Name=name self.Ower=ower self.Width=width self.Length=length self.Heigh=heigh @classmethod#这个装饰器是专门供类使用的方法 def tell_info(cls):#cls代表类本身 print(cls) print("---",cls.tag) @staticmethod#静态方法 叫类的工具包,不跟类绑定也不跟实例绑定 def wash_body(a,b,c): print("%s %s %s 正在洗澡" %(a,b,c)) Room.wash_body("北爷","喵爷","修电脑")#用类调用washbody这个方法 r1=Room("厕所","北爷",2,2,20000)#实例化一个实例r1 r1.wash_body("北爷","喵爷","修电脑")#用实例调用washbody这个方法 C:\python35\python3.exe D:/pyproject/day25/静态方法.py 北爷 喵爷 修电脑 正在洗澡 北爷 喵爷 修电脑 正在洗澡
查看下 这个静态方法是不是存到了类的属性字典里面
class Room: tag=1#定义一个类的数据属性 def __init__(self,name,ower,width,length,heigh): self.Name=name self.Ower=ower self.Width=width self.Length=length self.Heigh=heigh @classmethod#这个装饰器是专门供类使用的方法 def tell_info(cls):#cls代表类本身 print(cls) print("---",cls.tag) @staticmethod#静态方法 叫类的工具包,不跟类绑定也不跟实例绑定 def wash_body(a,b,c): print("%s %s %s 正在洗澡" %(a,b,c)) Room.wash_body("北爷","喵爷","修电脑")#用类调用washbody这个方法 print(Room.__dict__)#查看下静态方法 结果是定义到了类的属性字典里面了
总结:
静态属性:property类和实例都可以访问静态属性
(把函数封装成一个数据属性,让外面的人感受不 到是调用的函数属性)
类方法: classmethod只能类访问类方法,不能用实例访问类方法
静态方法:staticmethod 用类可以调用静态方法,实例也可以调用静态方法
不跟类和实例绑定,只叫类的工具包