ITPub博客

首页 > > > Python面向对象(二)

Python面向对象(二)

作者:Jack2k 时间:2021-01-12 09:30:19 0 删除 编辑

图标


类的析构函数

  • 使用预定义的__del__()作为析构函数,在真实删除实例对象时被调用
  • demo1:
# 在删除dc1的时候,解释器会调用__del__析构函数
# 真实删除:当前对象的引用数为0时 或 当前程序退出(垃圾回收)
  • demo1升级版:
# dc1  dc2都是对真实对象的一个引用
# del dc1 并没有删除真实对象,至少删除了该对象的一个引用“或者说指针”,因此这条语句不产生任何打印输出
# 接着,输出dc2.name 即 “老王”
# 最后当前程序退出,垃圾回收,会调用析构函数,打印“再见 老王”

# 程序开发中,一般不写析构函数,尽量通过垃圾回收机制处理
  • python类的内存管理

1)在删除对象时,Python解释器会检查引用次数

2)引用次数不为0,仅仅删除当前引用;为0,则删除对象---内存建立机制会判断对内存空间的引用次数,一旦发现某段内存空间没有指向它的指针,则它将不再会被找到,因此毫无意义,必须完全回收该空间

3)程序退出,则由垃圾回收机制删除对象

4)从两个角度看待对象:①真实存在的内存空间②指向该内存空间的指针(可能由无数个)

  • 如何获取对象的引用次数 sys.getrefcount(<对象名>) 函数返回值为真实被引用值+1

单元小结

  • 只要类构建完成、默认生成类对象、类属性,类属性本就是在类命名空间中声明的变量
  • 若要生成实例对象,则需要使用__init__();若需要删除实例对象,则需要使用__del__()函数

实例分析

计算客户流等待ATM机的平均等待时间:假设银行仅有1台ATM机,有n为顾客来银行操作ATM机器,求客户流等待ATM机的平均等待时间

  • 封装对象,重点思考对象间交互
  • ATM机:ATM类,假设只有1台
  • 客户流:Customer类
  • 等待队列的维护原理:队列中保存着next_time时间前即将到达的所有客户的到达时间,以及最多一个超过next_time时间的客户到达时间,该队列始终不空。一旦等待队列为空,则增加一个客户,队列不空保证时间前进时。next_time时间后,归属于下一个循环。
  • next_time受ATM机驱动;ATM对象处理完当前任务时,时间前进;ATM对象不处理任务,时间前进1

代码如下:

'''
ATM机器前 客户需要等待的时间 计算
'''
import random
class ATM():
    def __init__(self,maxtime=5):  # 实例化ATM机
        self.t_max = maxtime
    def getServCompleteTime(self,start=):
        '''获取每次ATM服务完成的时间值'''
        return start+random.randint(1,self.t_max)

class Customers():
    def __init__(self,n):# 表示当前有n个顾客
        self.count = n
        self.left = n
    def getNextArrvTime(self,start = ,arrvtime = 10):
        if self.left != :
            self.left-=1
            return start+random.randint(1,arrvtime)
        else:
            return 
    def isOver(self):
        return True if self.left== else False

c = Customers(100)
a = ATM()
wait_list = []  #等待队列不为空
wait_time = 
cur_time = 
cur_time += c.getNextArrvTime()##???
wait_list.append(cur_time) #把每个在排队的人 物化成 某一时刻
while len(wait_list) !=  or not c.isOver():
    if wait_list[] <=cur_time:
        next_time = a.getServCompleteTime(cur_time)
        del wait_list[]
    else:
        next_time = cur_time+1

    if not c.isOver() and len(wait_list) ==:
        next_arrv = c.getNextArrvTime(cur_time)
        wait_list.append(next_arrv)

    if not c.isOver() and wait_list[-1] < next_time:
        next_arrv = c.getNextArrvTime(wait_list[-1])
        wait_list.append(next_arrv)
        while next_arrv < next_time and not c.isOver():
            next_arrv = c.getNextArrvTime(next_arrv)
            wait_list.append(next_arrv)
    for i in wait_list:
        if i <= cur_time:
            wait_time += next_time-cur_time
        elif cur_time < i <next_time:
            wait_time += next_time-i
        else:
            pass
    cur_time = next_time
print(wait_time/c.count)

下面对各个模块的代码进行分析:

  • ATM类

ATM的最长操作时间为maxtime,可能操作时间为随机分布,范围是[1,maxtime],均为整数。实例方法getServCompleteTime()是为了返回ATM当前操作结束的时刻,若start=0,则说明是第一个客户,他对ATM操作的当前结束时刻为此次ATM的操作时长;否则就累加start代表的时长,为当前操作结束的时刻。

  • 客户类

1)设置self.count为客户总数n,设置self.left为初始剩余客户总数;

2)getNextArrvTime():如果还有剩余客户,则返回从某个时间点start(默认start=0,从时刻0开始计算)加上下一位客户到ATM的时间,下一位客户到ATM的时间为随机分布,范围在[1,arrvtime]之间,均为整数。

3)isOver() 判断是否还有剩余客户

  • 初始值设定

1)wait_list为等待队列,wait_time为n客户的等待时间和,cur_time为当前时间;

2)用getNextArrvTime()返回客户到达时间(第一位客户,此时start=0),并更新当前等待时刻cur_time

3)第一位客户到达后,自动加入等待队列,等待时间为0

  • 什么情况下执行主程序:

1)等待队列不为空或还有剩余客户,需要执行主程序

2)使用or而不是and 是因为可能发生等待队列为空,但是仍存在剩余客户的情况,即arrvtime时间内,等待队列一直没有新增客户;也可能发生所有人都在队列中等待但没有剩余客户的情况。

  • 第一个if语句:将排第一的客户移除排队列表去操作ATM。通过a.getServCompleteTime(cur_time)计算第一名用户操作完ATM的时间,并从队列中删除该客户。
  • 第二个if语句:当前排队列表为空,但是仍存在有客户,因此通过c.getNextArrvTime(cur_time)计算下个客户到达的时间,并增加到队列里。
  • 第三个if语句:为了避免ATM闲置
  • 统计等候时间:分段统计等候时间
  • 更新时间:当前的next_time更新为cur _time,进入下一个循环


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/36/viewspace-3141242/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: 我看中台
请登录后发表评论 登录
全部评论

注册时间:2007-12-08

  • 博文量
    214
  • 访问量
    17838