2017-06-28 4 views
0

Ich möchte die simpy Store ändern Funktionalität erhalten, indem das Objekt zu verändern, die in _do_get zurückgegeben:Ändern Simpy Shop _do_get

class mod_Store(Store): 
    def _do_get(self, event): 
     super()._do_get(event) 
     event.value.tagged = True 

env = Environment() 
s = mod_Store(env) 

class thing: 
    pass 

def putter(): 
    while True: 
     yield s.put(thing()) 
     yield env.timeout(5) 


def getter(): 
    while True: 
     t = yield s.get() 
     yield env.timeout(3) 

env.process(putter()) 
env.process(getter()) 

env.run(until=20) 

Grundsätzlich bevor das Objekt wieder zu Getter zurückkehren, würde ich gerne zu füge ein Attribut hinzu (tagged). Aber dieser Code die folgenden Fehler erzeugt:

--------------------------------------------------------------------------- 
AttributeError       Traceback (most recent call last) 
<ipython-input-50-27e09b52b41a> in getter() 
    19  while True: 
---> 20   t = yield s.get() 
    21   yield env.timeout(3) 

C:\ProgramData\Anaconda3\lib\site-packages\simpy\resources\base.py in __init__(self, resource) 
    77   self.callbacks.append(resource._trigger_put) 
---> 78   resource._trigger_get(None) 
    79 

C:\ProgramData\Anaconda3\lib\site-packages\simpy\resources\base.py in _trigger_get(self, put_event) 
    223    get_event = self.get_queue[idx] 
--> 224    proceed = self._do_get(get_event) 
    225    if not get_event.triggered: 

<ipython-input-50-27e09b52b41a> in _do_get(self, event) 
     3   super()._do_get(event) 
----> 4   event.value.tagged = True 
     5 

C:\ProgramData\Anaconda3\lib\site-packages\simpy\events.py in value(self) 
    132   if self._value is PENDING: 
--> 133    raise AttributeError('Value of %s is not yet available' % self) 
    134   return self._value 

AttributeError: Value of <StoreGet() object at 0x9030c88> is not yet available 

The above exception was the direct cause of the following exception: 

AttributeError       Traceback (most recent call last) 
<ipython-input-50-27e09b52b41a> in <module>() 
    24 env.process(getter()) 
    25 
---> 26 env.run(until=20) 

C:\ProgramData\Anaconda3\lib\site-packages\simpy\core.py in run(self, until) 
    135   try: 
    136    while True: 
--> 137     self.step() 
    138   except StopSimulation as exc: 
    139    return exc.args[0] # == until.value 

C:\ProgramData\Anaconda3\lib\site-packages\simpy\core.py in step(self) 
    227    exc = type(event._value)(*event._value.args) 
    228    exc.__cause__ = event._value 
--> 229    raise exc 

AttributeError: Value of <StoreGet() object at 0x9030c88> is not yet available 

durch base.py Sehen, ich sehe, dass _trigger_get in der init Funktion Get aufgerufen wird, so macht es Sinn, dass dies nicht funktioniert, aber wie kann ich erreichen, was Ich möchte erreichen? Eine Problemumgehung, die ich habe, besteht darin, die Attributzuweisung in einem try/catch zu tun und AttributeErrors zu fangen, aber das fühlt sich an wie ein Hack.

Auch wenn ich eine Druckanweisung am Anfang von _do_get hinzufügen wird es tatsächlich zweimal drucken und dann die Ausnahme auslösen, die ich seltsam finde.

Antwort

1

Vielleicht können Sie das Ereignis von der Unterklasse ableiten und das Attribut festlegen, wenn die Methode succeed() aufgerufen wird. Sie würden auch auch brauchen Store wie diese Unterklasse:

class TaggedStoreGet(StoreGet): 
    def succeed(self, value=None): 
     self.tagged = True 
     return super().succeed(value) 


class TaggedStore(Store): 
    get = BoundClass(TaggedStoreGet) 

habe es nicht getestet, aber ich denke, es könnte funktionieren.