2017-06-28 1 views
0

J'aimerais modifier le magasin simpy obtenir la fonctionnalité en modifiant l'objet qui est retourné dans _do_get:Modification Simpy magasin _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) 

En fait, avant de retourner l'objet à getter, je voudrais ajouter un attribut (étiqueté). Mais ce code produit l'erreur suivante:

--------------------------------------------------------------------------- 
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 

En regardant à travers base.py, je vois que _trigger_get est appelée dans la fonction init de Get, donc il est logique que cela ne fonctionne pas, mais comment puis-je accomplir ce que Je veux accomplir? Une solution que j'ai est juste pour faire l'attribution d'attribut dans un AttributeErrors try/catch et attraper, mais cela se sent comme un hack.

De plus, si j'ajoute une déclaration d'impression au début de _do_get il fait imprimer deux fois, puis soulever l'exception, que je trouve bizarre.

Répondre

1

Peut-être que vous pouvez sous-classer l'événement StoreGet et définir l'attribut lorsque sa méthode succeed() est appelée. Vous devrez également nous aussi sous-classe Store comme ceci:

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


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

ai pas testé, mais je pense que cela pourrait fonctionner.