本章重点
- 通过声明私有化属性、方法,保护和控制数据(重点)
- 通过property属性的使用,即控制好数据又方便访问(重点、难点)
- 明确__new__方法的作用和用法(重点)
- 通过单例模式,控制实例个数(难点)
- 使用异常处理机制,处理异常,提高代码健壮性
- 利用动态语言特点,动态添加属性和方法
- 利用__slots__属性控制可动态的属性
私有化属性
概述
前面学习面向对象过程中,修改类属性都是直接通过类名修改的。如果有些重要属性不想让别人随便修改,或者防止意外修改,该怎么办?
为了更好的保存属性安全,即不能随意修改,将属性定义为私有属性,添加一个可调用的方法去访问(就像一个安全口,只有在允许的情况下可以从这个入口进入,使用属性)
语法
两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问
使用私有属性的场景
- 把特定的一个属性隐藏起来 不想让类的外部进行直接调用
- 我想保护这个属性,不想让属性的值随意的改变
- 保护这个属性 不想让派生类【子类】去继承
特性
- 私有化属性不能在类外面访问
- 私有化属性可以在类里面访问,修改
- 子类不能继承私有化属性
class Person:
__hobby='跳舞' #私有的类属性
def __init__(self):
self.name='李四'
self.age=30
pass
# xl=Person()
# # print(xl.name) #可以访问
######私有化name###################
class Person:
def __init__(self):
self.__name='李四' #加两个下划线 将此属性私有化之后 就不能再外部直接访问了,当然在类的内部是可以访问的
self.age=30
pass
#####私有化属性在内部使用#####
def __str__(self):
'''
私有化的属性在内部可以使用 self.__name
:return:
'''
return '{}的年龄是{} 爱好是{}'.format(self.__name,self.age,Person.__hobby)
# xl=Person()
# # print(xl.__name) #这样是在外部访问的(离开了类) 不能访问私有属性
# print(xl) ##结果显示了str方法里的内容,可见私有属性是可以在内部使用的
######
class Person:
__hobby='跳舞' #私有的类属性
def __init__(self):
self.__name='李四' #加两个下划线 将此属性私有化之后 就不能再外部直接访问了,当然在类的内部是可以防蚊贴
self.age=30
pass
def __str__(self):
'''
私有化的属性在内部可以使用 self.__name
:return:
'''
return '{}的年龄是{} 爱好是{}'.format(self.__name,self.age,Person.__hobby)
def changeValue(self):
Person.__hobby='唱歌'
####说明子类是否可用继承私有属性#####3
class Student(Person):
def printInfo(self):
# print(self.__name) #在此访问父类中的私有属性 可以吗? 不可以
print(self.age)
pass
stu=Student()
# print(stu.__name)####结果显示无法调用父类的私有属性
stu.printInfo()
stu.changeValue() #修改私有属性的值
print(stu)
# print(stu.__hobby) #实例对象访问类属性
# print(Person.__hobby) #实例对象访问类属性
结论
- 私有化的【实例】属性 不能再外部直接的访问 可以在类的内部随意的使用
- 子类不能继承父类的私有化属性【只能继承父类公共的属性和行为】
- 在属性名的前面直接加‘ __’ (两个下划线) 就可以变为私有化了
私有化方法
概述
私有化方法跟私有化属性概念一样,有些重要的方法,不允许外部调用,防止子类意外重写,把普通的方法设置成私有化方法
语法
私有化方法,即在方法名前面加两个下划线
特性
- 私有化方法一般是类内部调用,子类不能继承,外部不能调用
- 单下划线、双下划线、头尾双下划线说明
_xxx 前面加一个下划线,以单下划线开头的表示的是 protected 类型的变量,即保护类型 只能允许其本身与子类进行访问,不能使用from xxx import * 的方式导入。
__xxx__ 前后两个下滑线,魔法方法,一般是python自有,开发者不要创建这类型的方法。
xxx_ 后面单下滑线,避免属性名与python关键字冲突
class Animal:
def __eat(self):
print('吃东西')
pass
def run(self):
self.__eat() #在此调用私有化的方法,类的内部是可用调用私有化方法的
print('飞快的跑')
pass
class Bird(Animal):
pass
b1=Bird()
# print(b1.eat())##不可以
# b1.eat()
b1.run()
Property属性函数
概述
上节我们讲了访问私有变量的话,一般写两个方法一个访问,一个修改,由方法去控制访问