2011-11-17 12 views
10

यह बहुत टूट गया है, मुझे आशा है कि तुम मेरे साथ दयालु हैं:कॉललाटर और एडकॉलबैक कैसे गठबंधन करें?

reactor.callLater(0, myFunction, parameter1).addCallback(reactor.stop) 
reactor.run() 

myFunction रिटर्न एक आस्थगित।

मुझे आशा है कि यह स्पष्ट है कि मैं क्या करना चाहते हैं:

  • जैसे ही रिएक्टर चल रहा है, मैं myFunction कॉल करना चाहते हैं। यही कारण है कि मैं देरी पैरामीटर के रूप में 0 का उपयोग कर रहा हूँ। क्या कॉललाटर को छोड़कर कोई दूसरा रास्ता नहीं है? यह इसके बारे में 0.
  • मैं रिएक्टर बंद करने के लिए जैसे ही myFunction कार्य पूरा कर लिया है चाहता हूँ एक देरी पारित करने के लिए अजीब लग रहा है।

समस्याओं मैं अब तक है:

  • AttributeError: DelayedCall instance has no attribute 'addCallback'। काफी उचित! मैं myFunction द्वारा शुरू की गई कॉलबैक श्रृंखला में कॉलबैक कैसे लगा सकता हूं?
  • exceptions.TypeError: stop() takes exactly 1 argument (2 given)

दूसरी समस्या मैं एक विशेष समारोह को परिभाषित करने के लिए किया था हल करने के लिए:

def stopReactor(result): 
    gd.log.info('Result: %s' % result) 
    gd.log.info('Stopping reactor immediatelly') 
    reactor.stop() 

और करने के लिए कोड बदलने के लिए:

reactor.callLater(0, myFunction, parameter1).addCallback(stopReactor) 
reactor.run() 

(अभी भी, callLater समस्या की वजह से काम नहीं कर रहा है, लेकिन stopReactor अब काम करेगा)

क्या reactor.stop पर कॉल करने के लिए वास्तव में कोई अन्य तरीका नहीं है एक अतिरिक्त समारोह जुर्माना?

उत्तर

19

IReactorTime.callLater और Deferredtwisted.internet.task.deferLater द्वारा मिश्रित किए गए हैं।

from twisted.internet import reactor, task 

d = task.deferLater(reactor, 0, myFunction, parameter1) 
d.addCallback(lambda _: reactor.stop()) 
reactor.run() 
+0

मुझे यह विकल्प बहुत पठनीय लगता है। 'लैम्ब्डा ने अनदेखा किया' थोड़ा सा जादू दिखता है: क्या आप यह स्पष्ट कर सकते हैं कि यह वास्तव में क्या करता है? – dangonfast

+4

किसी डिफरर्ड पर कॉलबैक को तर्क के साथ बुलाया जाता है। 'reactor.stop' कोई तर्क नहीं लेता है। 'lambda अनदेखा: reactor.stop()' स्वीकार करता है और तर्क, इसे अनदेखा करता है, और कोई तर्क के साथ 'reactor.stop' कहते हैं। –

+3

यह लिखने के लिए थोड़ा और पारंपरिक होगा: 'lambda _: reactor.stop' – DonGar

1

जैसे ही मेरा फ़ंक्शन ने कार्य पूरा कर लिया है, मैं रिएक्टर को रोकना चाहता हूं।

तो, एक रैपर बनाएं जो मेरा कार्य करता है और फिर रिएक्टर को रोक देता है?

def wrapper(reactor, *args): 
    myFunction(*args) 
    reactor.stop() 

reactor.callLater(0, wrapper, reactor, ...) 
0

आप के बाद से callLater एक समारोह वापस नहीं करता है, आस्थगित कि myfunction रिटर्न के लिए कॉलबैक संलग्न करने के लिए की जरूरत है। ऐसा कुछ काम कर सकता है:

reactor.callLater(0, lambda: myFunction(parameter1).addCallback(lambda _: reactor.stop()) 

लेकिन इसका परीक्षण नहीं किया गया है।

आप एक नया समारोह लिखने की ज़रूरत (यहाँ लैम्ब्डा _: reactor.stop()) क्योंकि एक हमेशा टाल के लिए कॉलबैक तो अप करने के लिए परिणाम ले।

def ignoringarg(f): 
    return lambda _: f() 

और फिर कार्य करें::

reactor.callLater(0, lambda: myFunction(paramater1).addCallback(ignoringarg(reactor.stop))) 

आप पाते हैं अपने आप को उनके साइड इफेक्ट के लिए कॉलबैक का उपयोग करना चाहते हैं और आप मान अक्सर प्रचार के बारे में परवाह नहीं है, तो आप एक छोटे से सहायक समारोह निर्धारित कर सकते हैं (Deferred कक्षा के लिए __rshift__ (और जगह में एनालॉग) को परिभाषित करना वास्तव में साफ होगा, ताकि जब आप तर्क को त्यागना चाहते हैं, तो myFunction(parameter1) >>= someotherfunc जब आप तर्क छोड़ना चाहते हैं, तो myFunction(parameter1) >> reactor.stop कर सकते हैं। यदि आपको लगता है कि दुर्व्यवहार हैकेलिश वाक्यविन्यास "साफ" है, वैसे भी।)

0

आप कुछ कार्रवाई के साथ कॉलबैक को गति प्रदान करने की जरूरत है, बस इसे (संभवतः वहाँ आस्थगित लौटने के लिए, या बराबर करने की कोई जरूरत नहीं है) है। बस चीजों को स्पष्ट करने के लिए (पूरी तरह से स्थगित का उपयोग करके):

from twisted.internet import reactor, defer 

# That will be our deferred to play with 
# it has callback and errback methods 
d = defer.Deferred() 

def my_function(x): 
    print 'function', x 
    # need to trigger deferred upon function run? 
    # Lets tell it to do so: 
    d.callback(x) 

# That's our callback to run after triggering `d`  
def d_callback(y): 
    print 'callback ', y 

# now let's bind that callback to be actually launched by `d` 
d.addCallback(d_callback) 

# now adding another callback just to stop reactor 
# note lambda simply helps to agree number of arguments 
d.addCallback(lambda data: reactor.stop()) 

# so we'll call `my_function` in 2 secs, then it runs 
# then it triggers `d` to fire its callbacks 
# then `d` actually detonates the whole chain of its added callbacks 

reactor.callLater(2, my_function, 'asdf') # 'asdf' is some stupid param 

# Here how it works 
print 'Lets start!' 
reactor.run() 
print 'Done!' 
संबंधित मुद्दे