如何在 Simpy 中缩进多个 with 语句?

How can I indented in multiple with statement in Simpy?

我尝试使用多个 'with' 语句构建一个简单的模型,如下所示。 然而,基于缩进,结果是不同的。 请告诉我缩进的明确规则是什么。

import simpy
import random

class Pre_Define:
    warmup_period = 1440
    sim_duration = 14400
    number_of_runs = 1 #3
    n_edbed = 77

class Patients:
    def __init__(self, p_id):
        self.id = p_id
        self.bed_name = ""
        self.admission_decision = ""
    def admin_decision(self):
        admin_decision_prob = random.uniform(0, 1)
        if admin_decision_prob <= 0.7:
            self.admission_decision = "DIS"
        else:
            self.dmission_decision = "IU"
        return self.admission_decision

class Model:
    def __init__(self, run_number):
        self.env = simpy.Environment()
        self.pt_ed_q = simpy.Store(self.env )
        self.pt_counter = 0
        self.tg = simpy.Resource(self.env, capacity = 4)
        self.physician = simpy.Resource(self.env, capacity = 4)
        self.bed_clean = simpy.Store(self.env)
        self.bed_dirty = simpy.Store(self.env)
        self.IU_bed = simpy.Resource(self.env, capacity = 50)  
        self.bed_transporter = simpy.Resource(self.env, capacity = 10) 
        # self.bed_cleaner = simpy.Resource(self.env, capacity = 2)
        self.run_number = run_number
        
    def generate_beds(self):
        for i in range(Pre_Define.n_edbed):
            yield self.env.timeout(0)
            yield self.bed_clean.put(f'bed{i}')
       # print(self.bed_clean.items)
       
    def generate_pt_arrivals(self):
        while True:
            self.pt_counter += 1
            pt = Patients(self.pt_counter)
            yield self.env.timeout(5)
            self.env.process(self.ed_process(pt))

    def clean_beds_process(self, cleaner_id):
        while True:
            bed = yield self.bed_dirty.get()
            #print(f'{self.env.now:.2f}  cleaner {cleaner_id} has started to clean bed {bed}')
            # clean bed
            yield self.env.timeout(50)
            #print(f'{self.env.now:.2f}  cleaner {cleaner_id} has finish cleaning bed {bed}')
            # put bed in clean bed queue, loop to wait for next dirty bead
            yield self.bed_clean.put(bed)

    def ed_process(self, pt):
        # process for treating a patient
        #print(f'{self.env.now:.2f}  patient  {pt.id} has arrived')
        with self.tg.request() as req:
            yield req
            yield self.env.timeout(10)
        #print(f'{self.env.now:.2f}  patient  {pt.id} has been triaged')
        bed = yield self.bed_clean.get()
        pt.bed_name = bed
        #print(f'{self.env.now:.2f}  patient {pt.id} has a clean EU bed {bed}')

        with self.physician.request() as req:
            yield req
            yield self.env.timeout(10)
        
        pt.admin_decision()
        #print(f'{self.env.now:.2f} patient {pt.id} has admission descesion of {pt.admission_decision}')

        if pt.admission_decision == "DIS":
            with self.IU_bed.request() as req:
                print(f'{self.env.now:.2f} patient {pt.id} is waiting IU bed')
                yield req
                with self.bed_transporter.request() as transreq:
                    print(f'{self.env.now:.2f} patient {pt.id} is waiting transporter')
                    yield transreq
                    yield self.env.timeout(15)   
                    
                dirty_bed_name = pt.bed_name
                yield self.bed_dirty.put(dirty_bed_name)
                print(f'{self.env.now:.2f} patient {pt.id} moved to IU and give up {dirty_bed_name}')
    
                yield self.env.timeout(600)
                print(f'{self.env.now:.2f} IU bed is available')
        else:
            # patient leaves EU
            dirty_bed_name = pt.bed_name
            #Bed_Mgmt.check_q(pt_id, self.pt_ed_q, self.bed_clean, self.bed_dirty, self.bed_cleaner)
            yield self.bed_dirty.put(dirty_bed_name)
            #print(f'{self.env.now:.2f}  patient {pt.id} left EU giving up bed {dirty_bed_name}')

    def run(self):
        self.env.process(self.generate_pt_arrivals())
        self.env.process(self.generate_beds())

        # creating and starting two cleaners
        for i in range(2):
            self.env.process(self.clean_beds_process(i+1))
        
        #self.env.run(until = Pre_Define.warmup_period + Pre_Define.sim_duration)
        self.env.run(until = 650)

for run in range(Pre_Define.number_of_runs):
    run_model = Model(run)
    run_model.run()
    print()

没有错误,只是缩进不同

例如, 案例 1>

if pt.admission_decision == "DIS":
            with self.IU_bed.request() as req:
                print(f'{self.env.now:.2f} patient {pt.id} is waiting IU bed')
                yield req
                with self.bed_transporter.request() as transreq:
                    print(f'{self.env.now:.2f} patient {pt.id} is waiting transporter')
                    yield transreq
                    yield self.env.timeout(15)   
                    
                dirty_bed_name = pt.bed_name
                yield self.bed_dirty.put(dirty_bed_name)
                print(f'{self.env.now:.2f} patient {pt.id} moved to IU and give up {dirty_bed_name}')
    
                yield self.env.timeout(600)
                print(f'{self.env.now:.2f} IU bed is available')

案例2>

                if pt.admission_decision == "DIS":
            with self.IU_bed.request() as req:
                print(f'{self.env.now:.2f} patient {pt.id} is waiting IU bed')
                yield req
                with self.bed_transporter.request() as transreq:
                    print(f'{self.env.now:.2f} patient {pt.id} is waiting transporter')
                    yield transreq
                    yield self.env.timeout(15)   
                    
                    dirty_bed_name = pt.bed_name
                    yield self.bed_dirty.put(dirty_bed_name)
                    print(f'{self.env.now:.2f} patient {pt.id} moved to IU and give up {dirty_bed_name}')
                yield self.env.timeout(600)
                print(f'{self.env.now:.2f} IU bed is available')

案例3>

        if pt.admission_decision == "DIS":
            with self.IU_bed.request() as req:
                print(f'{self.env.now:.2f} patient {pt.id} is waiting IU bed')
                yield req
                with self.bed_transporter.request() as transreq:
                    print(f'{self.env.now:.2f} patient {pt.id} is waiting transporter')
                    yield transreq
                    yield self.env.timeout(15)   
                    
                    dirty_bed_name = pt.bed_name
                    yield self.bed_dirty.put(dirty_bed_name)
                    print(f'{self.env.now:.2f} patient {pt.id} moved to IU and give up {dirty_bed_name}')
                    yield self.env.timeout(600)
                    print(f'{self.env.now:.2f} IU bed is available')

我不确定“with”后如何缩进...

资源在指定代码结束时被释放。对于任何“with”,在缩进结束时调用 close。 “with”的另一个常见用例是读取文件或流。由于脏床铺是无限的,我认为情况 1 和情况 2 运行 相同。技术差异是在案例 1 中,传输器在 yield self.env.timeout(15) 行之后被释放。而在情况 2 中,它是在 print(f'{self.env.now:.2f}.... 语句之后发布的。在案例 3 中,IU 床和传输器都在最后被释放,保持传输超时(600)

我觉得情况1就是你想要的