Day 21 封装,多态,私有成员,类方法,静态方法,类的属性,异常处理
01 昨日内容回顾
02 作业讲解
--------------------------------------------------------------------
03 面向对象的三大特征:封装,多态
封装:将一些数据,重要的信息等等放到一个地方(空间中)。
class A:
country = 'China'
area = '深圳'
def __init__(self,name,age):
self.name = name
self.age = age
a2 = A('小华',23)
print(a2.__dict__)
多态:一种事物有多种形态。
class Animal():
def __init__(self):
pass
def animal_talk(self,obj):
obj.talk()
class Dog(Animal):
def talk(self):
print('wang,wang')
python 会约定俗称制定一些行为规范,保持一致性。
class A:
def func1(self):
print('in A func1')
def func2(self):
print('in A func2')
class B:
def func1(self):
print('in B func1')
def func2(self):
print('in B func2')
将 A,B里面相似的一些功能命名成相同的名字,隐约制定一个标准
--------------------------------------------------------------------
04 类的约束
# 对类进行一些正确引导,约束,统一规范,满足正确的开发方式。
# 归一化设计
# 两种解决方式:
# 1,python常用的一种,在父类写一个相同的方法pay 在此方法里面,主动抛出一个错误,你应该在自己的类中定义此方法。(工作中常用)
# 用第一种是python经常用的解决方式。
class A(): # 这个父类制定了一个约束,规范,子类一定要有pay方法。
def pay(self,money):
raise Exception('未定义pay方法')
class Alipay(A):
def pay(self,money):
print('此次消费%s'% money)
def pay(obj,money): # 归一化设计
obj.pay(money)
a = Alipay()
pay(a,100) # 如果子类没有pay方法就抛出异常
解决方式2:在父类引用元类的抽象方法,抛出异常。
from abc import ABCMeta,abstractmethod
class A(metaclass=ABCMeta): # 这个父类制定了一个约束,规范,子类一定要有pay方法。
'''
抽象类,接口类:制定一个规范,强制执行。
'''
@abstractmethod
def pay(self,money):
pass
def func(self):
pass
class Alipay(A):
def pay(self,money):
print('此次消费%s'% money)
--------------------------------------------------------------------
05 类的私有成员
按照公有,私有对 类进行划分。
class Boss:
name = 'alex' # 公有静态属性 公有静态字段
__secretary = ['女1', '男2', '眼膜'] # 私有静态属性 私有静态字段
def __init__(self,username,password):
self.username = username # 公有对象属性 公有普通字段
self.__password = password # 私有对象属性 私有普通字段
def func(self):
print(self.__password)
print(self.__secretary)
def __func(self): # 私有方法
print('经常跟秘书加班....')
class Boss_son(Boss):
def func(self):
print(self.__secretary)
# 私有成员: 私有静态属性 私有对象属性 私有方法
class Boss():
__secretary = ['小三1','小三2'] # 私有静态属性
1.私有静态属性(仅类内部可以访问)
# 私有静态属性
1).类外部不能访问
# print(Boss.name)
# print(Boss.__secretary)
2).类内部能访问
b = Boss('addit',123)
b.func()
3).派生类不能访问
2.私有对象属性(仅类内部可以访问)
1).类外部不能访问
b = Boss('addit',123)
print(b.__password)
2).类内部能访问
print(b.func())
3).派生类不能访问
3.私有方法(仅类内部可以访问)
1).类外部不能访问
2).类内部能访问
def __func(self): # 私有方法
print('经常跟秘书加班....')
def fun1(self):
return self.__func()
3).派生类不能访问
总结:
对于这些私有成员来说,他们只能在类的内部使用,不能再类的外部以及派生类中使用.
ps:非要访问私有成员的话,可以通过 对象._类__属性名,但是绝对不允许!!!
为什么可以通过._类__私有成员名访问呢?因为类在创建时,如果遇到了私有成员(包括私有静态字段,私有普通字段,私有方法)它会将其保存在内存时自动在前面加上_类名.
--------------------------------------------------------------------
06 类方法,静态方法,属性
类方法:
# 类方法
class A:
name = 'barry'
@classmethod # 类方法
def func2(cls):
print(cls)
print(777)
def func1(self):
print(self)
# 类方法 他是通过类名直接调用的方法,类方法里面至少有一个参数,第一个参数默认cls
# print(A) # <class '__main__.A'>
# A.func2() # <class '__main__.A'>
# 对象可否调用类方法?
# 通过对象也可以调用类方法,cls 接受的不是对象空间而是类空间。
# a = A()
# a.func2() # <class '__main__.A'>
# a.func1() # <__main__.A object at 0x000001DC31E4F358>
静态方法:
# class A:
#
# name = 'barry'
#
# @staticmethod
# def func(): # 无需self参数
# print(666)
# obj = A()
# A.func()
# obj.func()
# 为什么要静态方法;相似功能,保持一致性
属性:将一个方法伪装成属性,虽然在代码逻辑上没什么提高,但是让其看起来更合理一些
class Market:
def __init__(self,name,price,discount):
self.name = name
self.__price = price
self.__discount = discount
@property
def price(self):
return self.__price * self.__discount
@price.setter
def price(self,new_price):
self.__price = new_price / self.__discount
@price.deleter
def price(self):
del self.__price
apple = Maket('apple',8,0.95)
print(apple.price) # 实际上是触发了 @property
apple.price = 7 # 实际上是触发了 @price.setter
del apple.price # 实际上是触发了 @price.deleter
--------------------------------------------------------------------
07 异常处理
# 解决异常的方式:
# 1,利用if语句解决异常,只能处理简单少量的异常。
# 2,异常处理,try .....except
# python解释器检测到错误,触发异常(也允许程序员自己触发异常
# 程序员编写特定的代码,专门用来捕捉这个异常(这段代码与程序逻辑无关,与异常处理有关)
# 如果捕捉成功则进入另外一个处理分支,执行你为其定制的逻辑,使程序不会崩溃,这就是异常处理
1.单支:
try:
lis = [1,2,3]
except ValueError as e:
print(e)
2.多支:
try:
except ValueError :
print("值错误")
except Exception as e:
print(e)
# 以上这三种分情况讨论:
# 1,如果你对报错信息不关系,只是想直接跳过报错而不分流执行代码。 万能异常最好。
# 2,如果你想要捕捉具体的错误信息,根据不同的错误执行不同的分支。多分支比较好。
3.一般采用多分枝 + 万能异常
4. try except else finally
try:
l1 = [1, 2, 3]
# l1[100] # IndexError
dic = {}
dic['key1']
except IndexError:
print(666)
else:
print('出现异常不执行else语句,没有异常就执行else语句')
finally:
print('finally有没有异常都执行finally语句')
# finally有没有异常都执行finally语句,要他有何用?
# 1,关闭文件句柄,数据库链接等。
# 2,函数,return 循环的break 之前执行finally操作
5, 主动抛出异常
# 主动抛出异常(用过)。
# try:
# raise TypeError('类型错误')
# except Exception as e:
# print(e)
6,自定义异常
# class PhoneconnectionError(BaseException):
# pass
#
# try:
# raise PhoneconnectionError('连接错误...')
# except PhoneconnectionError as e:
# print(e)
# 条件不成立 主动报错
# assert 1 == 2