一、静态属性
把类的函数属性封装成数据属性,使实例能像调用数据属性那样调用函数属性
class Room():
def __init__(self,name,owner,width,length):
self.name=name
self.owner=owner
self.width=width
self.length=length
@property #类似于装饰器,把函数属性封装为数据属性,把逻辑封装
def cal_area(self):
return self.width*self.length
r1=Room('wc','alex',18,1)
print(r1.cal_area)
print(r1.__dict__)
执行结果:
18
{'name': 'wc', 'owner': 'alex', 'width': 18, 'length': 1}
通过@property的装饰,使函数属性的调用方法变成了数据属性的调用方法可以封装逻辑,也即为封装的一种,但实例的属性字典并没有该属性。
二、类方法
类方法不通过实例访问类的函数属性就是类方法,这样的函数只能访问类属性,因为默认参数是cls
class Room():
tag=1
def __init__(self,name,owner,width,length):
self.name=name
self.owner=owner
self.width=width
self.length=length
@classmethod
def tell_info(cls):
print(cls)
print(cls.tag) #类的数据属性,不能访问实例的属性
Room.tell_info()
r1=Room('wc','alex',18,1)
r1.tell_info() #实例也可调用,但一般不这样做,没有意义
执行结果:
<class '__main__.Room'>
1
<class '__main__.Room'>
1
类方法通过@classmethod来定义,主要是为类提供的函数属性,但是实例也可调用(一般不这样做)。
三、静态方法
静态方法又叫类的工具包,通过@staticmethod定义,只是名义上属于类管理,并不和类与实例绑定,因为该函数默认并没有self和cls,
但类和实例都可通过点的方式调用如:类调用:Room.test(1,2,3)实例调用:r1.test(1,2,3),看代码
class Room():
tag=1
def __init__(self,name,owner,width,length):
self.name=name
self.owner=owner
self.width=width
self.length=length
@classmethod
def tell_info(cls):
print(cls)
print(cls.tag)
@staticmethod
def test(a,b,c):
print('%d + %d + %d = %d' %(a,b,c,a+b+c))
def test1(x,y): #注意参数a的颜色变化,函数默认把变量x当作了self,也即是类中函数定义中第一个参数默认就为实例的
print(x,y)
Room.test(1,2,3)
r1=Room('wc','alex',18,1)
r1.test(1,2,3)
print(Room.__dict__)
Room.test1(1,2) #类调用是不受影响
r1.test1(1) #默认是实例本身传过去,该句执行结果:<__main__.Room object at 0x000001E6E324D5B0> 1
总体执行结果:
1 + 2 + 3 = 6
1 + 2 + 3 = 6
{'__module__': '__main__', 'tag': 1, '__init__': <function Room.__init__ at 0x00000185877E0AF0>, 'tell_info': <classmethod object at 0x0000018587728400>, 'test': <staticmethod object at 0x000001858773DDC0>, 'test1': <function Room.test1 at 0x00000185877E0CA0>, '__dict__': <attribute '__dict__' of 'Room' objects>, '__weakref__': <attribute '__weakref__' of 'Room' objects>, '__doc__': None}
1 2
<__main__.Room object at 0x000001858773D5B0> 1
小结:1、静态属性只是把函数属性封装成实例的数据属性从而隐藏了其中的逻辑,但不会在实例的属性字典中(__dict__),
仍然只在类的属性字典中
2、类方法默认的是针对类的函数属性,因为默认添加参数cls(代表类),针对实例的函数属性默认添加参数self(代表实例)
他们都会点的形式调用,并且不用添加如调用类方法,Room.tell_info()
3、通过类方法和静态方法发现self针对实例,cls针对类,而静态方法两者都没有,说明和实例、类都没有进行绑定说明不能调用
类和实例的属性
4、实例的体现是出现self而类是cls,特殊情况是类方法和静态方法的出现才会产生特殊情况如上