面向对象编程-下
1.私有化属性
语法:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。
使用私有化属性的场景:
1.把特定的一个属性隐藏起来,不让类的外部进行直接调用。
2.不让属性的值随意改变。
3.不让子类继承。
class Person():
def __init__(self):
self.name='里斯'
self.age=30
pass
pass
xl=Person()
print(xl.name)
#私有化
class Pri():
def __init__(self):
self.__name='李四' #如此外界就访问不到了,但是在内部可以访问到
self.age=12
pass
def __str__(self):
return '{}的年龄是{}'.format(self.__name,self.age)
pass
ll=Pri()
print(ll)
print(ll.__name)
#私有化
class Pri():
def __init__(self):
self.__name='李四' #如此外界就访问不到了,但是在内部可以访问到
self.age=12
pass
def __str__(self):
return '{}的年龄是{}'.format(self.__name,self.age)
pass
class Student(Pri):
def pri(self):
print(self.__name) ##同样的,子类也访问不到私有属性
pass
pass
stu=Student()
stu.pri()
小结:
1.私有化的实例属性和类属性不能在外部直接访问,可以在类的内部随意访问。
2.子类不能继承父类的私有化属性,只能继承父类中公开的属性和行为。
3.如果想将属性私有化,直接在属性名的前面加两个下划线’__'就可以了。
4.私有化属性的值可以在类内部修改。
2.私有化方法
私有化方法即在方法名前面加两个下划线。
class Animal:
def eat(self):
print('吃')
pass
def run(self):
print('跑')
pass
pass
class Bird(Animal):
pass
b1=Bird()
b1.eat()
b1.run()
#私有化方法
class Pr():
def __eat(self):
print('私有化的吃')
pass
def run(self):
self.__eat()
print('跑')
pass
pass
b2=Pr()
b2.run()
b2.__eat()
私有化方法一般是类内部调用,子类不能继承,外部不能调用
前面一个单下划线:标识protected类型即保护类型的变量,只能允许其本身与子类进行访问,不能使用from ... import *的方式导入
前后两个双下划线:魔法方法
后面单下划线:避免属性名与python关键字冲突
前面双下划线:私有化,private
#访问私有变量的话一般写两个方法,一个访问一个修改,由方法去控制访问
class Person:
def __init__(self):
self.__age=19
pass
def get_age(self): #访问
return self.__age
def set_age(self,age): #修改
if age<0:
print('年龄不能小于0')
pass
else:
self.__age=age
pass
pass
pass
p=Person()
p.set_age(12)
print(p.get_age())
p2=Person()
p.set_age(-1)
3.属性函数property
若想直接像访问公共属性一样访问私有属性而不是如同上述使用方法访问私有属性,可以使用属性函数。
法一:
#访问私有变量的话一般写两个方法,一个访问一个修改,由方法去控制访问
class Person:
def __init__(self):
self.__age=19
pass
def get_age(self):
return self.__age
def set_age(self,age):
if age<0:
print('年龄不能小于0')
pass
else:
self.__age=age
pass
pass
#定义一个类属性,实现通过直接访问属性的形式去访问私有的属性
age=property(get_age,set_age)
pass
p=Person()
print(p.age)
p.age=25
print(p.age)
法二:使用装饰器
#访问私有变量的话一般写两个方法,一个访问一个修改,由方法去控制访问
class Person:
def __init__(self):
self.__age=12
@property #用装饰器添加属性标识,提供一个getter方法
def age(self):
return self.__age
@age.setter #提供一个setter方法
def age(self,parms): #修改私有属性的值,parms也就是后传入想要修改成的age
if parms<0:
print('年龄不能小于0')
pass
else:
self.__age=parms
pass
pass
pass
p1=Person()
print(p1.age)
p1.age=20
print(p1.age)
4.__new__方法
5.单例模式
单例模式是常用软件设计模式的一种,目的是确保某一个类中只有一个实例存在。如果希望在某个系统中,某个类只能出现一个实例,整个单例模式就能满足要求。
#创建一个单例对象 基于__new__实现
class DataBaseClass(object):
def __new__(cls, *args, **kwargs):
#cls._instance=cls.__new__(cls) 不能使用自己的new方法,容易造成递归死循环,应该调用父类的new方法
if not hasattr(cls,'_instance'): #如果不存在就创建
cls._instance=super().__new__(cls,*args,**kwargs)
return cls._instance
pass
db1=DataBaseClass()
print(id(db1))
db2=DataBaseClass()
print(id(db2)) #可以看出来都是一个对象
class DBoptSingle(DataBaseClass):
pass
d1=DBoptSingle()
print(id(d1))
d2=DBoptSingle()
print(id(d2)) #子类继承后也都是一个
6.错误与异常处理
有时候代码写错了执行程序的时候,执行到错误代码程序会直接种植报错,这是因为python检测到一个错误时,解释器就无法继续执行了,出现了错误的提示,这就是“异常”。
#语法格式:
try:
可能出现错误的代码块
except:
出错之后执行的代码块
else:
没有出错的代码块
finally:
不管有没有出错都执行的代码块
将可能出错的代码放到try里面,except可以指定类型捕获异常。except里面的代码是捕获到异常时执行。
#异常处理
try:
print(b) #要捕获异常的代码
pass
except NameError as msg: #将异常信息输出
#处理异常,捕获到异常就来这里
print(msg)
pass
print('处理好了Name异常')
如果不是一个类型的异常是不会捕获的
#异常处理
try:
li=[1,2,3,3] #要捕获异常的代码
print(li[10])
pass
except NameError as msg:
#处理错误,捕获到错误就来这里
print(msg)
pass
print('处理好了Name异常')
因为是index异常而不是name异常,所以try-except语句没起到捕获异常的作用。
#异常处理
try:
li=[1,2,3,3] #要捕获异常的代码
print(li[10])
pass
except NameError as msg:
#处理错误,捕获到错误就来这里
print(msg)
pass
except IndexError as msg:
print(msg)
pass
print('处理好了异常')
这样就捕获到了。
python中内置的异常类型