10.12 类属性
10.12.1 类属性的定义与特点
类属性与实例属性
类属性
:类对象拥有的属性,被类对象和实例对象共有,内存中只存在一份副本,如果是公有类属性,可以通过类对象和实例对象访问
类属性:在类的内部,方法外面定义,所有对象共享,占一份内存
10.12.2 类属性的访问
print('第一种方法:通过类对象进行访问')
print(BmwCar.brand)
print('第二种:通过实例对象进行访问')
obj1 = BmwCar('x1','白色')
print(obj1.brand)
print('###########################################################)
class BmwCar(object):
brand = 'BMW'
__money = 10
_num = 200
def __init__(self,style,color):
self.style = style
self.color = color
def printmoney(self):
print(self.__money)
print(BmwCar.__money)
if __name__ == '__main__':
print('第一种方法:通过类对象进行访问')
print(BmwCar.brand)
# print(BmwCar.__money)
print(BmwCar._num)
# print('第二种:通过实例对象进行访问')
obj1 = BmwCar('x1','白色')
print(obj1.brand)
# print(obj1.__money)
print(obj1._num)
obj1.printmoney()
注意点:
1、类属性的分类:公有类属性,私有类属性、保护类属性
2、私有类属性不可以在类的外部访问,包括实例对象或者类对象均不行
3、在类的内部,实例方法中,可以通过类对象和实例对象访问
10.12.3 修改类属性
class BmwCar(object):
brand = 'BMW'
__money = 10
_num = 200
def __init__(self,style,color):
self.style = style
self.color = color
if __name__ == '__main__':
print('#########通过类对象进行修改##########')
print(BmwCar.brand)
BmwCar.brand = '宝马'
print(BmwCar.brand)
print('############通过实例对象来修改############')
b1 = BmwCar('x1','白色')
b1.brand = '大众'
print(b1.brand)
print(BmwCar.brand)
注意点:
1、类属性通过类对象来修改
2、不可以通过实例对象来修改,否则增加的只是一个动态属性(init里面如果有这个字段就覆盖)而已
10.13 类方法
class BmwCar(object):
brand = 'BMW'
__money = 10
_num = 200
def __init__(self,style,color):
self.style = style
self.color = color
@classmethod
def changebrand(cls):
pass
print('#########################')
class BmwCar(object):
brand = 'BMW'
__money = 10
_num = 200
def __init__(self,style,color):
self.style = style
self.color = color
@classmethod
def changebrand(cls):
cls.brand = '大众'
print(cls)
if __name__ == '__main__':
BmwCar.changebrand()
print('类方法之后',BmwCar.brand)
obj = BmwCar('x1','白色')
obj.changebrand()
print(obj.brand)
注意点:
1、类方法的格式
@classmethod
def 方法名(cls):
pass
2、可以修改类属性
3、可以通过类对象访问,也可以通过实例对象访问
10.14 静态方法
class BmwCar(object):
brand = 'BMW'
__money = 10
_num = 200
def __init__(self,style,color):
self.style = style
self.color = color
@classmethod
def changebrand(cls):
cls.brand = '大众'
print(cls)
@staticmethod
def showinfo():
print('静态方法')
if __name__ == '__main__':
BmwCar.changebrand()
print('类方法之后',BmwCar.brand)
BmwCar.showinfo()
obj = BmwCar('x1','白色')
obj.changebrand()
obj.showinfo()
print(obj.brand)
展示:
<class '__main__.BmwCar'>
类方法之后 大众
静态方法
<class '__main__.BmwCar'>
静态方法
大众
注意点:
1、格式,需要装饰器 @staticmethod
2、不需要self,cls
3、通过类对象与实例对象进行调用
4、就是类里面的普通函数
10.15 单例模式
class BmwCar(object):
# 创建一个私有类属性为空
__instance = None
def __new__(cls, *args, **kwargs):
# super().__new__(cls,*args,**kwargs)
# 判断私有类属性是否为None,是就将父类object中的__new__方法赋给它,不是None就返回该私有类属性
if cls.__instance is None:
obj = object.__new__(cls)
cls.__instance = obj
return cls.__instance
注意点:
1、重写new方法
2、重写的new方法必须返回生成的实例对象
优点:
1、在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是同样的一个实例,确保所有的对象访问的一个实例
2、提供了对唯一实例的受控访问
3、内存中只有一个对象,节约系统资源
4、可以实现可变数目的实例
5、避免对资源的多重占用
缺点:
1、不适用变化的对象,单例会引起数据错误
2、扩展有困难
3、开销问题
应用场景:
资源管理类一般设计成单例模式
需要频繁实例化然后销毁的对象
创建对象耗时或者耗费资源过多但又经常用到的对象
有状态的工具类对象
频繁访问数据库或者文件的对象