Ⅰ、类属性、类方法(类和实例都能调用类属性和类方法)
类是一个特殊的对象,Python 中 一切皆对象:class AAA:#定义的类属于 类对象obj1 = AAA() #属于 实例对象除了封装 实例 的 属性 和 方法外,类对象 还可以拥有自己的 属性 和 方法:·类属性·类方法(方法前面要加上@classmethod装饰器。不用实例化就可以执行类的方法)通过 类名. 的方式可以 访问类的属性 或者 调用类的方法(方法的参数中要用cls参数且放到最前)
class A:a=1@classmethoddef aa(cls):print("这是类方法")s=A()print(A.a)#调用属性1A.aa() #调用方法这是类方法print(s.a)1s.aa()这是类方法class B:def __init__(self):self.a=1def aa(self):print("这是实例方法")m=B()>>>print(B.a)Traceback (most recent call last):File "<stdin>", line 1, in <module>AttributeError: type object 'B' has no attribute 'a'>>>B.aa()Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: aa() missing 1 required positional argument: 'self'>>>B.aa(m)#具体原因可以参考之前self的文章,请点入口1这是实例方法>>>print(m.a)1>>>m.aa()这是实例方法
入口1
Ⅱ、私有属性与公有属性
在定义类的属性时,如果属性名以两个下划线“__”开头则表示是《私有属性》,否则是《公有属性》。①私有属性在类的外部不能直接访问,需要调用对象的“公有成员方法”来访问,或者②通过python支持的特殊方式来访问。Python提供了访问私有属性的特殊方式,可用于程序的测试和调试,对于成员方法也有同样性质。方法如下:对象名._类名+私有成员例如:访问Car类私有成员__weightcar1._Car__weight注意:私有属性是为了数据封装和保密而设的属性,一般只能在类的成员方法(类的内部)中使用访问,虽然Python支持一种特殊的方式来从外部直接访问类的私有成员,但是并不推荐这种做法。
#在类的成员方法(类的内部)中使用访问class Car:price =1000 #定义类属性,类和对象访问def __init__(self,c,w):self.color=c #定义共有属性color,对象访问self.__weight=w #定义私有属性__weight,类和对象都不能访问def siyou(self):return self.__weightcar1 = Car("red",10.5)>>>print(Car.price)1000>>>print(Car.color)Traceback (most recent call last):File "<input>", line 1, in <module>AttributeError: type object 'Car' has no attribute 'color'>>>print(car1.price)1000>>>print(car1.color)red>>>print(car1.__weight)Traceback (most recent call last):File "<stdin>", line 1, in <module>AttributeError: 'Car' object has no attribute '__weight'>>>print(car1.siyou())10.5
Ⅲ、私有方法、公有方法
私有方法、公有方法都属于对象,私有方法的名字以两个下划线“__”开始,每个对象都有自己的公有方法和私有方法,在这两类方法中可以访问属于类和对象的成员;①公有方法通过对象名直接调用,②私有方法不能通过对象名直接调用,只能在属于对象的方法中通过“self”调用,或者外部通过Python支持的特殊方式来调用
class Test:def __test2(self):print("这是私有方法")def test(self):print("这是公有方法1")def _test(self):print("这是公有方法2")self.__test2()t=Test()>>>t.test()这是公有方法1>>>Test.test()Traceback (most recent call last):File "<input>", line 1, in <module>TypeError: test() missing 1 required positional argument: 'self'>>>t._test()这是公有方法2这是私有方法>>>t.__test 'Test' object has no attribute '__test'
Ⅳ、静态属性、类方法(上面提到过)、静态方法
一、静态属性
静态属性说的就是数据属性,把方法变成像属性一样调用
1、定义一个房间的类,求下这个房间的面积
class Room:def __init__(self,name,ower,width,length,heigh):self.Name=nameself.Ower=owerself.Width=widthself.Length=lengthself.Heigh=heighdef 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()#实例调用类的函数属性会自动传实例本身作为参数输出结果:北爷 住的厕所 总面积是4平米的地下室喵爷 住的北京 总面积是1200平米的地下室
1、1 property装饰器
class Room:def __init__(self,name,ower,width,length,heigh):self.Name=nameself.Ower=owerself.Width=widthself.Length=lengthself.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输出结果:北爷 住的厕所 总面积是4平米的地下室喵爷 住的北京 总面积是1200平米的地下室
1.2 这样还不行。因为正常的数据属性直接运行是没有返回值的
现在改为了直接return一个返回值,现在用起来的效果就是跟调用数据属性是一模一样的了,property这个装饰器就是把类的函数属性变为数据属性,也就是封装成了数据属性
class Room:def __init__(self,name,ower,width,length,heigh):self.Name=nameself.Ower=owerself.Width=widthself.Length=lengthself.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这个实例的数据属性#输出结果:北爷 住的厕所 总面积是4平米的地下室喵爷 住的北京 总面积是1200平米的地下室厕所北京
二、python给我们提供了classmethod这个装饰器,只要用了这个方法, 就表示这个装饰器下面的方法是专门给类用的
这个方法就是只是类在调用类的方法,跟实例没关系,只要加了classmethod就只能供类调用
class Room:tag=1#定义一个类的数据属性def __init__(self,name,ower,width,length,heigh):self.Name=nameself.Ower=owerself.Width=widthself.Length=lengthself.Heigh=heigh@classmethod#这个装饰器是专门供类使用的方法def tell_info(cls):#cls代表类本身print(cls)print("---",cls.tag)#等价于Room.tagRoom.tell_info()#会自动把类本身传给cls#输出结果<class '__main__.Room'>--- 1
三、静态方法 叫类的工具包,不跟类绑定也不跟实例绑定。也就是说都能用
class Room:tag=1#定义一个类的数据属性def __init__(self,name,ower,width,length,heigh):self.Name=nameself.Ower=owerself.Width=widthself.Length=lengthself.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)#实例化一个实例r1r1.wash_body("北爷","喵爷","修电脑")#用实例调用washbody这个方法#输出结果:北爷 喵爷 修电脑 正在洗澡北爷 喵爷 修电脑 正在洗澡
总结:
静态属性:property类和实例都可以访问静态属性(把函数封装成一个数据属性,让外面的人感受不 到是调用的函数属性)
类方法: classmethod类访问类方法,实例也能访问类方法
静态方法:staticmethod 用类可以调用静态方法,实例也可以调用静态方法不跟类和实例绑定,只叫类的工具包
Ⅴ、python的命名规范
python中有几种比较有意思的命名的方式,__xxx__
、__name
、_name
、,下面分别说它们的用处。
【__xxx__】
在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”(魔术方法),是可以直接访问的。例如类的初始化方法__init__
,Python中所有的魔术方法均在官方文档中有相应描述
def __init__(self, name)
魔术方法大全,大家可以点这里参考一下
【__name】
双下划线开头,表示的是私有变量,为了让内部属性不被外部访问。
【_name】
_xxx被看作是“私有的”,在模块外不可以使用,在类外可以用。当变量是私有的时候,用_xxx 来表示变量是很好的习惯。单下划线 开始的成员变量叫做保护变量,意思是只有本模块、类、对象和子类对象自己能访问到这些变量,被导入时,该变量不能引用;
类属性 类方法;私有属性 公有属性;私有方法 公有方法;静态属性 静态方法;python的命名规范__xx__\__xx\_xx(自用笔记)