• PYTHON1.面向对象_day03


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

    上次内容回顾
    1. 多态
       1)什么是多态:同一个方法,在不同
          子类中有不同的表现
       2)方法的重写来实现
       3)保持程序的扩展性、灵活性
      
    2. 面向对象的技术特性
       1)构造方法与析构方法
         a)构造:__init__()
            调用时机:对象被创建时自动调用
            作用:创建对象属性,并赋值
            注意:子类构造方法显示调用父类构造
                  方法
         b)析构方法:__del__()
            调用时机:对象被销毁时调用
            作用:对象销毁时执行清理操作
           
       2)object类:所有类最终的父类
                    如果类定义时没有指定父类
                    默认从object中继承
                    __base__查看父类
      3)super()和issubclass()函数
          super(): 获得父类的绑定
          两种格式:super()  只能在类方法中使用
                    super(type, obj) obj必须是type示例化的对象
         
          issubclass():判断某个是不是另一个类的子类
          格式:issubclass(cls, cls_or_tuple)

      4)多重继承:一个类有多个父类
          MRO: 方法解析顺序,__mro__
               从下至上,从左至右
              
    3. 函数重写:让对象操作更方便
       1)对象转字符串函数
         str(): __str__(),返回字符串给人阅读
         repr():__repr__(),返回字符串给解释器阅读
     
       2)内建函数
         abs(): __abs__()
         len(): __len__()
         reversed(): __reversed()__
         round():__round()__
        
       3)数值转换函数
         int(): __int__()
         float(): __float__()
         complex(): __complex__()
         bool(): __bool__()
        
    4. 属性操作函数
       getattr(obj, name):获取对象属性
       setattr(obj, name, value):设置某个属性值
       hasattr(obj, name):判断对象有没有某个属性
       delattr(obj, name):删除某个属性值
      
    作业:见account.py


    今天内容
    1. 可迭代对象
       1)什么是迭代器
       2)代码特征:重写__iter__()方法返回可迭代对象
                    重写__next__()方法获取下一个元素
       3)__next__()方法,实现迭代器协议
          如果有下一个元素,则返回
          如果没有下一个元素,抛出StopIteration异常
       4)示例:见myiter.py

      1 # myiter.py
      2 # 通过函数重写,实现自定义迭代器
      3 class MyIter:
      4     #用列表初始化对象
      5     def __init__(self, lst):
      6         self.data = lst #lst是列表
      7         self.cur_index = 0 #计数器
      8 
      9     def __iter__(self):# 返回可迭代对象
     10         return MyIter(self.data)
     11 
     12     def __next__(self):# 获取下一个元素
     13         if self.cur_index >= len(self.data):
     14             raise StopIteration #抛出异常
     15         else:
     16             i = self.cur_index #记录计数器
     17             self.cur_index += 1 #计数器加1
     18             return self.data[i] #返回元素
     19 
     20 if __name__ == "__main__":
     21     myiter = MyIter(range(1,10))
     22     for x in myiter:
     23         print(x, end=" ")
     24 
    myiter.py

    myiter

    2. 运算符重载
       1)什么是运算重载:自定义类中,重写
         某些方法,重写后就可以对对象进行
         某些运算符操作
       2)目的
          a)简化对象操作。例如:
            c = "abc" + "123"
            d = "123" > "456"
          b)代码清晰、直观
          c)可以在类中自定义运算规则    
          注意:运算重载不要改变原有意义
     
       3)算术运算符重载
         - 重写方法后,支持+,-,*,//,/,%,**
         - 重载方法和运算符的对应关系
           __add__(self,rhs)   self + rhs
           __sub__(self,rhs)   self - rhs
           __mul__(self,rhs)   self * rhs
           __truediv__(self,rhs)   self / rhs
           __floordiv__(self,rhs)  self // rhs
           __mod__(self,rhs)       self % rhs
           __pow__(self,rhs)       self ** rhs

      
       课堂练习:在MyList类中,重载+,*运算符
               L1 = MyList([1,2,3])
               L2 = MyList([4,5,6])
               L1 + L2==>MyList([1,2,3,4,5,6])
               L1*2 ==> MyList([1,2,3,1,2,3])
               见mylist.py
              
         4)反向算术运算符重载
            在正向运算符重载的函数前面加r
            例如:__radd__(), __rsub__()...
            支持:2 + obj (对象在操作符右边)

        5)复合运算操作符
            在正向运算符重载的方法前加i前缀
            例如:__iadd__(), __isub__()...
            重载运算符后,执行复合表达式
            ojb += 2,首先查找__iadd__(),
            如果没有找到,则再查找__add__(),
            如果再没有找到,报TypeError异常
           
         6)比较运算符:>,<,>=,<=,==,!=
           - 重写方法和运算符的对照关系
             __lt__(self, rhs)   self < rhs
             __gt__(self, rhs)   self > rhs
             __eq__(self, rhs)   self == rhs
             __ne__(self, rhs)   self != rhs
             __ge__(self, rhs)   self >= rhs
             __le__(self, rhs)   self <= rhs

           - 示例:见truck.py

      1 # truck.py
      2 # 卡车类,演示运算符重载
      3 class Truck:
      4     def __init__(self, load):
      5         self.load = load #载重
      6 
      7     def __add__(self, value):#重载+运算符
      8         print("__add__()被调用")
      9         return Truck(self.load + value)
     10 
     11     def __mul__(self, value): #重载*运算符
     12         return Truck(self.load * value)
     13 
     14     #反向+运算符重载,支持 3 + truck操作
     15     def __radd__(self, value):
     16         print("__radd__()被调用")
     17         return Truck(self.load + value)
     18 
     19     # 符合运算符重载,支持obj += 2表达式
     20     # def __iadd__(self, value):
     21     #     print("__iadd__()被调用")
     22     #     return Truck(self.load + value)
     23 
     24     def __str__(self):
     25         return "load: %d" % self.load
     26 
     27     def __gt__(self, other): # 重载>运算符
     28         print("__gt__()方法被调用")
     29         if self.load > other.load:
     30             return True
     31         else:
     32             return False
     33 
     34     # def __lt__(self, other): # 重载<运算符
     35     #     if self.load < other.load:
     36     #         return True
     37     #     else:
     38     #         return False
     39 
     40 if __name__ == "__main__":
     41     t1 = Truck(20)
     42     t2 = Truck(25)
     43     print(t1 > t2)  # 调用__gt__()
     44     print(t1 < t2)  # 调用__lt__()
     45     #t = Truck(20)
     46     #t2 = t + 1 # t2接受返回的对象
     47     #t2 = 1 + t  # 调用__radd__()方法
     48     # t += 1 # 调用__iadd__()方法,如果没有该方法,调用__add__
     49     # print(t)
     50     # t3 = t * 4
     51     # print(t3)
    truck.py
    truck
           - 比较规则:
             >: 首先找__gt__(), 没有找__lt__()
                并将执行__lt__()结果取反
                如果__lt__()不存在则报错
             <: 规则和大于相反
             >=:首先找__ge__(), 没有找__le__()
                并将执行__le__()结果取反
                __le__()不存在则报错
             <=:规则和大于等于相反
             ==:首先找__eq__(), 如果不能存在则
                判断两个对象ID值,相同返回True
                不同返回False
             !=:首先找__ne__(),不存在则找
                __eq__()并执行取反
                如果__eq__()不存在则比较ID
                ID相同返回False,否则返回True
         
         课堂练习:在MyList类中,重载>,<,==,!=
           操作符,比较规则如下:
           等于:data属性元素个数相等
                 并且相同位置上的值相等
           大小比较:[1,2,4] > [1,2,3]
                     [1,2,3,4] > [1,2,3]
                     [1,2,4] > [1,2,3,4]
           代码见:mylist.py   
          
         7)一元运算符:带一个操作数的操作符
           __neg__(self)   -self  负号运算
           __pos__(self)   +self  正号运算
           __invert__(self) ~self 取反运算

          
           作用:重写上述方法,支持对象如下操作:
                 -obj, +obj, ~obj
                
         8)in/not in运算符重载
            只需要重载__contains__(self,e)
            in运算,则直接调用__contains__()
            not in运算,调用__contains__()取反

        
         9)索引运算符重载:支持[]操作
            __getitem__(self,i)       self[i]
            __setitem__(self,i,value) self[i]=value
            __delitem__(self,i)       del self[i]

    3. 实例的内置属性
       1)__dict__属性:绑定实例自身的变量字典
          包括父类创建的属性和私有属性

          示例:
          am = AutoMobile("卡车","blue",4.0)
          print(am.__dict__)

         
      2)__class__属性:绑定创建该对象的类
         
    作业:   
    1)编写一个汽车租赁程序,包含汽车类(Car),
    客户类(Customer), 租车店类(CarStore),各个
    类包含的属性和方法有:
         Car类:
             属性
             car_id    车辆id号
             name    车辆名称
             is_lend    是否出租
             price    每天单价
             start_date    起租日期
             end_date    租赁终止日期
             方法
             __str__()
            
         Customer类:
             属性
             cust_id        客户编号
             cust_name    客户姓名
             tel_no        客户电话
             方法
             __str__()
         CarStore类:
             属性
             cars        所有车辆列表
             customers    所有客户列表
             方法
             __load_cars()    加载所有车辆信息
             __load_customers()    加载所有客户信息
             print_cars_info()    打印所有车辆信息
             find_car()            查找车辆
             add_car()            添加车辆
             del_car()            删除汽车
             lend()                租车
             back()                还车
    2)实现上述类,并编写测试代码
        

      1 # car_store.py
      2 # 汽车租赁模拟程序
      3 class Car: # 车辆类
      4     def __init__(self, car_id, name,
      5                  price, is_lend):
      6         self.car_id = car_id #车辆编号
      7         self.name = name #名称
      8         self.price = price #价格
      9         self.is_lend = is_lend #是否出租
     10         self.start_date = "" #起租日期
     11         self.end_date = "" #预计归还日期
     12         self.cust_id = "" #租车客户编号
     13 
     14     def __str__(self):
     15         ret = "车辆编号:%s,名称:%s,单价:%.2f," 
     16             "是否出租:%s" %(self.car_id,
     17             self.name, self.price,self.is_lend)
     18         return ret
     19 
     20 class Customer: #客户类
     21     def __init__(self,cust_id,cust_name,tel_no):
     22         self.cust_id = cust_id
     23         self.cust_name = cust_name
     24         self.tel_no = tel_no
     25 
     26     def __str__(self):
     27         ret = "客户编号:%s,客户名称:%s,电话:%s" 
     28           %(self.cust_id, self.cust_name, self.tel_no)
     29 
     30 class CarStore: #租车店类
     31     def __init__(self):
     32         self.cars = [] #车辆列表
     33         self.customers = [] #客户列表
     34         self.__load_cars() #加载车辆列表
     35         self.__load_customers()#加载客户列表
     36 
     37     def __load_cars(self): #加载车辆列表
     38         self.cars.append(Car("1","GOLF",400,""))
     39         self.cars.append(Car("2","凯越",350,""))
     40         self.cars.append(Car("3","奥迪",1200,""))
     41         self.cars.append(Car("4","凯美瑞",800,""))
     42         self.cars.append(Car("5","宝来",450,""))
     43 
     44     def __load_cars(self): #加载车辆列表,从文件中读取
     45         with open("/home/tarena/aid1805/lx/面向对象/day03/cars_list.txt") as f:
     46             line = f.readline(256).replace("
    ","")
     47             custinfo = line.split(",")
     48             car_id = custinfo[0]
     49             car_name = custinfo[1]
     50             price = float(custinfo[2])
     51             is_len = custinfo[3]
     52             car = Car(car_id,car_name,price,is_len)
     53             self.cars.append(car) #对象添加到列表
     54 
     55     def __load_customers(self):#加载客户列表
     56         cust1 = Customer("C0001","张大大","15811223344")
     57         cust2 = Customer("C0002","李小小","13233333444")
     58         cust3 = Customer("C0003","赵四","18044445555")
     59         self.customers.append(cust1)
     60         self.customers.append(cust2)
     61         self.customers.append(cust3)
     62 
     63     def print_cars_info(self): #打印车辆信息
     64         for car in self.cars: #遍历车辆列表并打印
     65             print(car)
     66 
     67     def find_car(self, car_id): #根据车辆编号查询
     68         for car in self.cars: #遍历车辆列表
     69             if car.car_id == car_id: #编号相等
     70                 print(car)
     71                 return
     72         print("未找到车辆信息")
     73         return
     74 
     75     def add_car(self, car): #添加车辆,car为Car的对象
     76         if isinstance(car, Car): #car是Car类的实例
     77             self.cars.append(car)
     78         else:
     79             print("对象类型有误")
     80         #可以增加id号是否存在的逻辑判断
     81         return
     82 
     83     def del_car(self, car_id): #根据车辆编号删除
     84         for car in self.cars:
     85             if car.car_id == car_id:
     86                 self.cars.remove(car) #删除对象
     87         return
     88 
     89     def lend(self, car_id, cust_id,
     90             start_date, end_date): #租车
     91         for car in self.cars:
     92             if car.car_id == car_id:
     93                 if car.is_lend == "":#已出租
     94                     print("该车辆已经出租")
     95                     return
     96                 else: #未出租
     97                     setattr(car, "is_lend", "")#改状态
     98                     setattr(car, "cust_id", cust_id)
     99                     setattr(car, "start_date", start_date)
    100                     setattr(car, "end_date", end_date)
    101                     print("车辆出租登记完成")
    102                     return
    103         print("未找到车辆信息")
    104         return
    105 
    106     def back(self, car_id): #还车
    107         for car in self.cars:
    108             if car.car_id == car_id:
    109                 setattr(car, "is_lend", "")#改状态
    110                 setattr(car, "cust_id", "")
    111                 setattr(car, "start_date", "")
    112                 setattr(car, "end_date", "")
    113                 print("还车登记完成")
    114                 return
    115         print("未找到该车辆信息")
    116         return
    117 
    118 if __name__ == "__main__":
    119     car_store = CarStore()  #实例化租车店对象
    120     car_store.print_cars_info() #打印车辆信息
    121     print("")
    122     #租车方法测试
    123     car_store.lend("3","C0001","2018-01-01","2018-01-03")
    124     car_store.print_cars_info()
    125 
    126     #还车方法测试
    127     car_store.back("3")
    128     car_store.print_cars_info()
    129 
    130      #添加车辆方法测试
    131     car_store.find_car("3") #查找编号为3的车辆
    132 
    133     car = Car("6","捷达",300,"")
    134     car_store.add_car(car)  #将car对象添加到cars列表
    135     car_store.print_cars_info()
    car_store.py
    car_store

  • 相关阅读:
    03-架构设计的目的
    02-架构设计的历史背景
    01-架构到底是指什么
    python 基础 1.5 python数据类型(四)--字典
    python 基础 1.5 python数据类型(三)--元组常用方法示例
    python 基础 1.5 python数据类型(三)--元组
    python 基础 1.5 python数据类型(二)--列表常用方法示例
    python 基础 1.5 数据类型(二)--列表
    python 基础 1.5 python 数据类型(一)--整型 浮点型 布尔型及字符串和常用方法
    python 基础 1.4 python运算符
  • 原文地址:https://www.cnblogs.com/shengjia/p/10387147.html
Copyright © 2020-2023  润新知