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

 

posted @ 2019-01-17 21:00  addit  Views(95)  Comments(0Edit  收藏  举报