2011-02-10 27 views
11

में असिंक्रोनस HTTP कॉल मुझे पाइथन में कॉलबैक प्रकार की कार्यक्षमता की आवश्यकता है, जहां मैं हर बार पैरामीटर में बदलाव के साथ एक वेब सेवा के लिए अनुरोध भेज रहा हूं। मैं चाहता हूं कि ये अनुरोध क्रमिक रूप से क्रमशः घटित हों, इसलिए मैं चाहता हूं कि फ़ंक्शन को असीमित रूप से कहा जाए।पाइथन

ऐसा लगता है कि एसिंककोर वह है जो मैं उपयोग करना चाहता हूं, लेकिन उदाहरणों के बारे में मैंने देखा है कि यह कैसे काम करता है, सभी ओवरकिल की तरह दिखते हैं, इसलिए मुझे आश्चर्य है कि अगर कोई और रास्ता है तो मुझे नीचे जाना चाहिए। मॉड्यूल/प्रक्रिया पर कोई सुझाव? आदर्श रूप में मैं कक्षाओं को बनाने के बजाय इन्हें प्रक्रियात्मक फैशन में उपयोग करना चाहता हूं लेकिन मैं इसके आसपास नहीं जा सकता।

+0

वे ओवरकिल। मुझे बस एक स्क्रिप्ट के भीतर से एक साथ http कॉल की आवश्यकता है (मुझे कमांड लाइन से एक प्रक्रिया को कॉल करने की आवश्यकता नहीं है)। मुझे बस कॉलबैक कार्यक्षमता की आवश्यकता है लेकिन मुझे इसके लिए पाइथन में प्रक्रिया नहीं मिल रही है। आगे का शोध मुझे urllib2 की तरफ ले जा रहा है। – kasceled

+1

ओवरकिल? थ्रेड के पास कमांड लाइन से कॉलिंग प्रक्रियाओं के साथ कुछ लेना देना नहीं है। – Falmarri

+0

tippytop, हाँ निश्चित रूप से परिवहन के लिए urllib2 .. लेकिन आपको अभी भी समानांतर में उन्हें फेंकने की जरूरत है। तो आप थ्रेडिंग, मल्टीप्रोसेसिंग, समवर्ती। फ्यूचर्स, या एसिंच I/o आधारित समाधान कर सकते हैं। –

उत्तर

8

Twisted framework सिर्फ इसके लिए टिकट है। लेकिन अगर आप इसे लेना नहीं चाहते हैं तो pycurl का उपयोग भी कर सकते हैं, libcurl के लिए रैपर, जिसका अपना एसिंक इवेंट लूप है और कॉलबैक का समर्थन करता है।

+0

जब मैंने इसे पोस्ट किया (देर से स्वीकृति के लिए खेद है) तो मैंने पीकुरल दृष्टिकोण वापस ले लिया। – kasceled

+1

@tippytop कूल। आप इसके शीर्ष पर अपने सरलीकृत रैपर में रुचि भी ले सकते हैं। [Pycopia.WWW.client] (http://code.google.com/p/pycopia/source/browse/trunk/WWW/pycopia/WWW/client.py) मॉड्यूल। – Keith

13

पायथन 3.2 में शुरू, आप समांतर कार्यों को लॉन्च करने के लिए concurrent.futures का उपयोग कर सकते हैं।

बाहर की जाँच करें इस ThreadPoolExecutor उदाहरण:

http://docs.python.org/dev/library/concurrent.futures.html#threadpoolexecutor-example

यह सूत्र एचटीएमएल पुनः प्राप्त करने के spawns और प्रतिक्रियाओं पर काम करता है के रूप में वे प्राप्त कर रहे हैं।

import concurrent.futures 
import urllib.request 

URLS = ['http://www.foxnews.com/', 
     'http://www.cnn.com/', 
     'http://europe.wsj.com/', 
     'http://www.bbc.co.uk/', 
     'http://some-made-up-domain.com/'] 

# Retrieve a single page and report the url and contents 
def load_url(url, timeout): 
    conn = urllib.request.urlopen(url, timeout=timeout) 
    return conn.readall() 

# We can use a with statement to ensure threads are cleaned up promptly 
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: 
    # Start the load operations and mark each future with its URL 
    future_to_url = {executor.submit(load_url, url, 60): url for url in URLS} 
    for future in concurrent.futures.as_completed(future_to_url): 
     url = future_to_url[future] 
     try: 
      data = future.result() 
     except Exception as exc: 
      print('%r generated an exception: %s' % (url, exc)) 
     else: 
      print('%r page is %d bytes' % (url, len(data))) 

उपरोक्त उदाहरण थ्रेडिंग का उपयोग करता है। वहाँ भी, एक समान ProcessPoolExecutor प्रक्रियाओं की एक पूल का उपयोग करता है बल्कि धागे से:

http://docs.python.org/dev/library/concurrent.futures.html#processpoolexecutor-example

import concurrent.futures 
import urllib.request 

URLS = ['http://www.foxnews.com/', 
     'http://www.cnn.com/', 
     'http://europe.wsj.com/', 
     'http://www.bbc.co.uk/', 
     'http://some-made-up-domain.com/'] 

# Retrieve a single page and report the url and contents 
def load_url(url, timeout): 
    conn = urllib.request.urlopen(url, timeout=timeout) 
    return conn.readall() 

# We can use a with statement to ensure threads are cleaned up promptly 
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: 
    # Start the load operations and mark each future with its URL 
    future_to_url = {executor.submit(load_url, url, 60): url for url in URLS} 
    for future in concurrent.futures.as_completed(future_to_url): 
     url = future_to_url[future] 
     try: 
      data = future.result() 
     except Exception as exc: 
      print('%r generated an exception: %s' % (url, exc)) 
     else: 
      print('%r page is %d bytes' % (url, len(data))) 
16

आप के बारे में eventlet को जानते हो? यह आपको सिंक्रोनस कोड के रूप में दिखाई देने वाला लिखने देता है, लेकिन यह नेटवर्क पर असीमित रूप से संचालित होता है।

यहाँ एक सुपर कम से कम क्रॉलर का एक उदाहरण है:

urls = ["http://www.google.com/intl/en_ALL/images/logo.gif", 
    "https://wiki.secondlife.com/w/images/secondlife.jpg", 
    "http://us.i1.yimg.com/us.yimg.com/i/ww/beta/y3.gif"] 

import eventlet 
from eventlet.green import urllib2 

def fetch(url): 

    return urllib2.urlopen(url).read() 

pool = eventlet.GreenPool() 

for body in pool.imap(fetch, urls): 
    print "got body", len(body) 
0

(हालांकि यह धागा सर्वर साइड अजगर के बारे में है के बाद से इस सवाल का एक समय पहले कहा गया था दूसरों जहां वे के लिए देख रहे हैं इस पर ठोकर सकता है।। क्लाइंट साइड पर एक समान उत्तर)

क्लाइंट साइड समाधान के लिए, आप Async.js लाइब्रेरी विशेष रूप से "नियंत्रण-प्रवाह" अनुभाग पर एक नज़र डालना चाहेंगे।

https://github.com/caolan/async#control-flow

एक "झरना" आप के साथ "समांतर" अपने वांछित परिणाम प्राप्त कर सकते हैं के संयोजन से। https://github.com/caolan/async#autotasks-callback जहां "लिखने:

झरना (समांतर (Taska, TaskB, TaskC) - -> PostParallelTask)

आप नियंत्रण-प्रवाह के तहत उदाहरण की जांच-पड़ताल" स्वचालित "वे आप ऊपर का एक उदाहरण देना -फाइल "" get_data "और" make_folder "और" email_link "पर निर्भर करता है लिखने-फ़ाइल पर निर्भर करता है"

कृपया ध्यान दें कि यह सब क्लाइंट पक्ष पर होता है (जब तक कि आप नोड कर रहे हों।जे एस - सर्वर साइड)

सर्वर साइड पायथन के लिए पर, @https://github.com/pycurl/pycurl/blob/master/examples/basicfirst.py

PyCURL पर देखने pyCurl साथ नीचे दिए गए उदाहरण के संयोजन से, आप गैर-अवरुद्ध मल्टी-थ्रेडेड कार्यक्षमता प्राप्त कर सकते हैं।

उम्मीद है कि इससे मदद मिलती है। सौभाग्य।

वेंकट @http://MyThinkpond.com