ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

PYTHON1.面向对象_day02

2019-02-16 10:54:30  阅读:289  来源: 互联网

标签:__ day02 self data 面向对象 print acct PYTHON1 def


课程:Python面向对象
进度:day2

上次内容回顾
1. 面向对象:以对象为中心
2. 三大特性:封装、继承、多态
3. 如何定义类、如何实现继承
     class 类名称(父类列表):
           # 构造函数
           # 其它成员函数

今天的内容
1. 多态:相同的方法,不同的表现(重点)
    1)事物除了共性外,还具有各自的特性(个性)
         多态就用来处理事物的个性
    2)多态能够在不影响父类行为(不修改父类代码)
         情况下,进行功能的扩展和变更
    3)使程序(软件设计)更具灵活性

2. 方法的重写:父类中定义过的方法子类中重新定义
    (重点)

3. 多态的实现:通过在子类中重写父类的方法实现多态(重点)
    (重点)
   
课堂练习:
编写一个手机类(Phone)
属性:名称(name), 价格(price),
           CPU, 屏幕尺寸( screen_size)
方法:开机(startup),关机(shutdown)
           打电话(call), 发短信(send_msg)
并编写测试代码
见 phone.py

  1 # phone.py
  2 # 手机类
  3 import time
  4 class Phone:
  5     def __init__(self, name, price,
  6                  CPU, screen_size):
  7         self.name = name
  8         self.price = price
  9         self.CPU = CPU
 10         self.screen_size = screen_size
 11 
 12     def startup(self):
 13         print("正在开机")
 14         time.sleep(2)
 15         print("开机成功")
 16 
 17     def shutdown(self):
 18         print("正在关机")
 19         time.sleep(2)
 20         print("关机成功")
 21 
 22     def call(self, phone_no):
 23         print("正在拨号")
 24         time.sleep(1)
 25         print("正在和%s通话" % phone_no)
 26 
 27     def send_msg(self, phone_no, msg):
 28         print("正在向%s发送信息..." % phone_no)
 29         time.sleep(2)
 30         print("【%s】发送成功" % msg)
 31 
 32     def __del__(self):  # 析构方法
 33         print("__del__方法被调用")
 34 
 35 def fun():
 36     phone = Phone("华为",1999.99,
 37                  "双核2G", 5.5)
 38     print("fun()函数退出")
 39 
 40 if __name__ == "__main__":
 41     myphone = Phone("华为",1999.99,
 42                     "双核2G", 5.5)
 43     fun()
 44     print("程序退出")
 45     # myphone程序退出时被销毁
 46 
 47 
 48 
 49     myphone.startup()  #启动
 50     myphone.call("13512345678") #打电话
 51     myphone.send_msg("13512345678","你好")
 52     myphone.shutdown()  #关机
phone.py

phone

4. 面向对象的技术特性
   1)构造和析构
      a)构造方法(重点)
        - 名称:在Python中,固定为__init__
        - 作用:是为对象创建属性,并且赋予初始值
        - 调用时机:对象被创建(实例化)自动调用
        - 如果在类中未定义,Python会给出默认的构造方法
        - 在继承关系中,如果父类定义了__init__方法
          在子类的构造方法中,必须要调用父类的构造方法

       b)析构方法
          - 名称:__del__
          - 调用时机: 对象被销毁时自动调用
                               del obj, 局部变量退出作用于,程序退出
          - 作用:对象销毁时,执行清理操作

   2)多重继承:一个类有多个父类
       - 如何实现多继承: 定义类的时候,继承自多个父类,
             父类之间用逗号隔开
       - 语法格式:
             class 类名称(父类1, 父类2, ......):
                     语句块

       - 通过多重继承,子类具有所有父类的特征和行为
       - 如果多个父类具有相同的方法(或属性名称),通过
         类的__mro__属性中记录的顺序进行方法查找

        MRO(Method Resolution Order)

        总的原则按照由下至上、从左至右(继承列表中前后)
         进行查找,直到object类,如果都没有找到就报错

  1 # mul_inh.py
  2 # 多重继承示例
  3 # 超人类继承自战士、飞行者、喷或者
  4 # 三个类
  5 class Fighter:  #战士类,默认继承自object
  6     def fight(self):
  7         print("我能战斗")
  8 
  9     def roar(self):  #吼叫
 10         print("战士吼叫:嗷嗷嗷")
 11 
 12 class Flyer:  #飞行者类
 13     def fly(self):
 14         print("我能飞行")
 15 
 16     def roar(self):  #吼叫
 17         print("飞行者吼叫:呜呜呜")
 18 
 19 class Firer: # 喷火者
 20     def fire(self):
 21         print("我能喷火")
 22 
 23 # 超人类,继承自Fighter,Flyer,Firer父类
 24 class SuperMan(Flyer,Fighter,Firer):
 25     pass
 26 
 27 if __name__ == "__main__":
 28     super_man = SuperMan() # 实例化超人对象
 29     super_man.fight()  # 超人战斗
 30     super_man.fly()    # 超人飞行
 31     super_man.fire()   # 超人喷火
 32     super_man.roar()   # 超人吼叫??
 33     # Mehtod Resolution Order
 34     # 决定调用哪一个类的方法
 35     # print(SuperMan.__mro__)
 36     print(SuperMan.__bases__) # __bases__绑定父类
 37     print(Fighter.__base__)
 38     print(Flyer.__base__)
 39 
mul_inh.py

mul  

3)object类:所有类的总父类,如果定义类时候,没有
       指定父类,则默认从object类继承

                         
       类的父类可以通过__base__属性查看

   4)super()和issubclass()
      - super()函数
        作用:返回绑定的父类
              有时候需要显式调用父类方法
              就使用super()函数
        格式:super(type, ojb) 返回obj对象父类
              super() 返回当前对象父类

                      只能在类的方法中调用

     - issubclass: 判断一个类是否是另一个
                    类的子类,如果是返回True
                    如果不是返回False
        格式:issubclass(cls, class_or_tuple)
        
5. 函数重写(重点,理解原理)
   1)对象转字符函数的重写
     - str:将对象转换成人阅读的字符串
            重写__str__()

     - repr: 返回字符串,给Python解释器阅读
             通过eval(repr(obj))能够还原obj
             对象,重写__repr__()

     - 当调用str(obj)将对象转换成字符串
       时,其搜索顺序为:
       + 优先查找obj.__str__()方法(包括父类)
       + 如果上一步不存在,则调用obj.__repr__()
       + 如果上一步不存在,则调用object.__repr__()

  1 
  2 class A:
  3     def __init__(self, name):
  4         self.name = name
  5 
  6     def __str__(self):  # 重写__str__函数
  7         return "name = %s" % self.name
  8 
  9 class B(A):
 10     def __init__(self, name, id):
 11         super().__init__(name) # 调用父类构造方法
 12         self.id = id  # id属性被创建
 13 
 14     def __repr__(self):  # 重写__repr__方法
 15         # 返回例如"B('Jerry','0001')"
 16         return "B('%s','%s')" % (self.name, self.id)
 17 
 18     def __str__(self):  # 重写__str__函数
 19         return "name=%s,id=%s"%(self.name,self.id)
 20 
 21 b = B("Jerry", "0001")  # ==》
 22 print(b)
 23 
 24 # str_obj = repr(b)
 25 # print(str_obj)
 26 # new_obj = eval(str_obj)  # 通过调用eval函数还原对象
 27 # print(new_obj)
 28 
 29 # print(b)  # B类中重写__str__方法,所以可以直接打印
 30 # str_obj = str(b)  # 将b对象转换成字符串
 31 # print(str_obj)
 32 
 33 #super(B, b).print() # 根据对象b找到父类,并调用父类的print
 34 # print(issubclass(B, (A,object)))    # True
 35 # print(issubclass(B,object)) # True
 36 # print(issubclass(A, B))  # False
a.py

  2)内建函数重写
     - abs()函数:重写__abs__()
     - len()函数: 重写__len__()
     - reversed()函数: 重写__reversed__()
     - round()函数:重写__round__()
    
     课堂练习:重写__len__()和__round__()
               重写__reversed__()
     示例见my_list.py

  1 # mylist.py
  2 # 自定义列表
  3 class MyList:
  4     def __init__(self, iterable=[]):
  5         self.data = [x for x in iterable]
  6 
  7     # 重写__abs__()函数
  8     def __abs__(self):
  9         #对每个元素求绝对值,用产生的结果实例化一个MyList对象
 10         return MyList(abs(x) for x in self.data)
 11 
 12     def __str__(self):  # 重写__str__()函数
 13         ret = ""
 14         for x in self.data:
 15             ret += str(x)  # 将元素由数字转换成字符串
 16             ret += " "
 17         return ret   # 返回结果串
 18 
 19     def __len__(self):  # 重写__len__函数,返回元素个数
 20         return len(self.data)
 21 
 22     # 对每个元素求近似值,并实例化对象返回
 23     def __round__(self):
 24         return MyList(round(x,2) for x in self.data)
 25 
 26     # 重写__reversed__,倒序
 27     def __reversed__(self):
 28         tmp = []
 29         x = len(self.data) - 1  # 最后元素下标
 30         while x >= 0:
 31             tmp.append(self.data[x])
 32             x -= 1   # 计数器减1
 33         return MyList(tmp)  # tmp是经过倒序的可迭代对象
 34 
 35     def __add__(self, other): # L1 + L2
 36         return MyList(self.data + other.data)
 37 
 38     def __mul__(self, value): # L1 * 2
 39         return MyList(self.data * value)
 40 
 41     def __eq__(self, other): # 重载==运算符
 42         len1 = len(self.data)  # 取data属性长度
 43         len2 = len(other.data) # 取另一个对象data的长度
 44         if len1 != len2: # 长度不相等,无需比较
 45             return False
 46 
 47         for i in range(0, len1):
 48             if self.data[i] != other.data[i]:
 49                 return False #只要出现元素不相等,返回False
 50         return True
 51 
 52     def __ne__(self, other): # 重载!=运算符
 53         return not (self == other)
 54 
 55     def __gt__(self, other):
 56         len1 = len(self.data)  # 取data属性长度
 57         len2 = len(other.data) # 取另一个对象data的长度
 58         min_len = min(len1, len2) # 获得循环上限
 59 
 60         for i in range(min_len): # 以长度短的作为循环上限
 61             if self.data[i] == other.data[i]:
 62                 continue
 63             elif self.data[i] > other.data[i]:
 64                 return True
 65             elif self.data[i] < other.data[i]:
 66                 return False
 67         if len1 == len2:  #相等
 68             return False
 69         elif len1 > len2: #前面的元素相等,长度比对方大
 70             return True
 71         else:
 72             return False
 73 
 74     def __neg__(self): #重载符号运算符
 75         return MyList(-x for x in self.data)
 76 
 77     def __contains__(self, e): # in/not in运算符重载
 78         print("__contains__()被调用")
 79         return e in self.data
 80 
 81     def __getitem__(self, i): # 重载[]取值操作
 82         return self.data[i]
 83 
 84     def __setitem__(self, i, value):#重载[]赋值操作
 85         self.data[i] = value
 86 
 87     def __delitem__(self, i): #重载[]删除操作
 88         del self.data[i]
 89 
 90 if __name__ == "__main__":
 91     L = MyList([-1, 2, -3, 4, -5])
 92     print(L[0])  # 索引取值
 93     L[2] = 333   # 通过索引设置值
 94     print(L)
 95     del L[3]     # 删除
 96     print(L)
 97 
 98     # print(2 in L)   # True
 99     # print(4 not in L) # False
100 
101     #print(-L)  # 对对象执行负号运算
102 
103     # L1 = MyList([1,3,5])
104     # L2 = MyList([1,3,5,7])
105     # print(L1 > L2)
106     # L = MyList([-1, 2, -3, 5.6789])
107     # L3 = MyList([3,4,5])
108     # print(L + L3)
109     # print(L * 2)
110     # print(2 * L)
111 
112     # print(reversed(L))  # 对象元素逆序并打印
113     # print(len(L))   # 打印返回的长度
114     # print(round(L)) # 打印新产生的对象
115     #                 # 每个元素都是原对象元素的近似值
116     # L2 = abs(L)  # 重写了__abs__()函数,支持abs表达式
117     # print(L2)  # 重写了__str__()函数,所以支持print()
my_list.py
   3)数值转换函数重写
     - int(): 重写__int__()
     - float(): 重写__float__()
     - complex(): 重写__complex__()
     - bool: 重写__bool__()
     示例见my_number.py

  1 # my_number.py
  2 # 自定义数字类型
  3 # 数值转换函数重写示例
  4 class MyNumber:
  5     def __init__(self, value):
  6         self.data = value #值,字符串
  7 
  8     def __int__(self):
  9         return int(float(self.data))
 10 
 11     def __float__(self):
 12         return float(self.data)
 13 
 14     def __complex__(self):
 15         return complex(self.data)
 16 
 17 if __name__ == "__main__":
 18     num = MyNumber("123.45")
 19     print(getattr(num, "data")) # "123.45"
 20     print(num.data)  # "123.45"
 21 
 22     setattr(num, "data", "456.78")
 23     print(getattr(num, "data")) #456.78
 24 
 25     print(hasattr(num, "data")) #True
 26     print(hasattr(num, "aaaa")) #False
 27 
 28     delattr(num, "data") #删除data属性
 29     print(hasattr(num, "data")) #False
 30 
 31     # print(int(num))  #将num对象转换成int
 32     # print(float(num))
 33     # print(complex(num))
my_number.py

my_number

6. 属性管理函数:操作对象属性
   1)getattr: 获取对象属性值
     - 格式: getattr(obj, name[,default])
     - 作用: getattr(x, "y") 等同于
              x.y表达式
             
   2)setattr: 设置对象属性值
     - 格式:setattr(obj, name, value)
     - 作用:setattr(x, "y", "zzz")等同于
             x.y = "zzz"表达式   
    
   3)hasattr: 判断有没有某个属性值
     - 格式:hasattr(obj, name)
     - 返回:布尔类型,有-True 没有-False
  
   4)delattr: 删除对象某个属性值
     - 格式:delattr(obj, name)
     - 作用:delattr(x, "y")等同于
             del x.y 表达式

作业:
1)编写一个账户类(Account)
    属性:账号(acct_no), 户名(acct_name),
          开户日期(reg_date),
          账户类型(acct_type)(借记卡/贷记卡),
          状态(acct_status)(正常,挂失,冻结,注销)
          余额(balance)
    方法:存款(diposite)
          取款(draw)
          冻结(freeze), 解冻(unfreeze)
          挂失(report_loss),解挂失(relieve_loss)
          修改账户信息(modify_acct_info)
2)编写测试代码

  1 # account.py
  2 # 账户类
  3 dict_status = {  #状态字典
  4   0:"正常",1:"冻结",2:"挂失",3:"销户"
  5 }
  6 dict_type = {0:"借记账户", 1:"贷记账户"}
  7 
  8 class Account:
  9     def __init__(self, acct_no, acct_name,
 10                  reg_date, acct_type,
 11                  acct_status, balance):
 12         self.acct_no = acct_no #账号
 13         self.acct_name = acct_name #户名
 14         self.reg_date = reg_date #开户日期
 15         self.acct_type = acct_type #类型
 16         self.acct_status = acct_status #状态
 17         self.balance = balance #余额
 18 
 19     def diposite(self, amt): #存款
 20         print("存款前余额:%.2f"%self.balance)
 21         self.balance += amt #修改余额
 22         print("存款后余额:%.2f"%self.balance)
 23 
 24     def draw(self, amt): #取款
 25         if self.acct_status == 0: #正常
 26             if self.balance < amt: #余额不足
 27                 print("余额不足")
 28                 return
 29             else:  #余额充足
 30                 print("取款前余额:%.2f" % self.balance)
 31                 self.balance -= amt #修改余额
 32                 print("取款后余额:%.2f" % self.balance)
 33         else:  #非正常状态
 34             print("状态不允许取款")
 35 
 36     def freeze(self): # 冻结
 37         if self.acct_status != 0:
 38             print("状态不允许冻结")
 39             return
 40         self.acct_status = 1 #状态置为冻结
 41         print("账户已冻结")
 42 
 43     def unfreeze(self): #解冻
 44         if self.acct_status != 1: #判断已冻结
 45             print("状态不允许解冻")
 46             return
 47         self.acct_status = 0 #状态置为正常
 48         print("账户已解冻")
 49 
 50     def __str__(self): #重写__str__()
 51         # 将状态转换为对应的字符串
 52         status = dict_status[self.acct_status]
 53         # 将类型转换为对应的字符串
 54         type = dict_type[self.acct_type]
 55         ret="账号:%s,户名:%s,开户日期:%s,类型:%s,状态:%s,余额:%.2f"\
 56             %(self.acct_no, self.acct_name, \
 57              self.reg_date, type, \
 58              status, self.balance)
 59         return ret
 60 
 61 if __name__ == "__main__":
 62     acct = Account("6223450001", "张大大",
 63                    "2018-01-01", 0, 0, 2000.00)
 64     acct.diposite(1000.00)  #存款
 65     acct.draw(500)  #取款
 66     print(acct)  #打印账户信息
 67     acct.freeze() #冻结
 68     print(acct)  #打印账户信息
 69     acct.unfreeze() #解冻
 70     print(acct)  #打印账户信息
 71 
 72 
 73 
 74 
account.py

acct

标签:__,day02,self,data,面向对象,print,acct,PYTHON1,def
来源: https://www.cnblogs.com/shengjia/p/10386957.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有