2012-08-05 8 views
11

कोडपायथन (पिक्यरी) में यह अनबाउंड चरणीय काम क्यों कर सकता है?

from pyquery import PyQuery 
d = PyQuery('<p class="hello">Hi</p><p>Bye</p>') 
d('p').filter(lambda i: PyQuery(this).text() == 'Hi') 

मेरा प्रश्न 3 लाइन में this है एक अबाध चर रहा है और वर्तमान वातावरण में परिभाषित नहीं किया जाता pyquery की गाइड से है, लेकिन इसके बाद के संस्करण कोड अभी भी काम करता है।

यह कैसे काम कर सकता है? यह NameError: name 'this' is not defined शिकायत क्यों नहीं करता है?

ऐसा लगता है कि https://bitbucket.org/olauzanne/pyquery/src/c148e4445f49/pyquery/pyquery.py#cl-478 पर कुछ होता है, क्या कोई इसे समझा सकता है? मॉड्यूल जिसमें समारोह परिभाषित किया गया था की वैश्विक नामस्थान -

+1

धन्यवाद, मैंने कभी भी PyQuery के बारे में नहीं सुना है। निश्चित रूप से कोशिश करने और इसका उपयोग करने जा रहा है। – Blender

+0

वही यहाँ। पहले PyQuery के बारे में कभी नहीं पता था, दिलचस्प लगता है .. – SuperSaiyan

उत्तर

4

यह पायथन के func_globals जादू है, जो

शब्दकोश कि समारोह के वैश्विक चर धारण करने के लिए एक संदर्भ है के माध्यम से किया जाता है।

आप PyQuery कोड में गोता हैं: क्योंकि चर समय वास्तविक समारोह कहा जाता है पर मौजूद हो सकता है

def func_globals(f): 
    return f.__globals__ if PY3k else f.func_globals 

def filter(self, selector): 
    if not hasattr(selector, '__call__'): 
     return self._filter_only(selector, self) 
    else: 
     elements = [] 
     try: 
      for i, this in enumerate(self): 

       # The magic happens here 
       func_globals(selector)['this'] = this 

       if callback(selector, i): 
        elements.append(this) 

     finally: 
      f_globals = func_globals(selector) 
      if 'this' in f_globals: 
       del f_globals['this'] 
     return self.__class__(elements, **dict(parent=self)) 
+0

धन्यवाद, बेसिकवॉल्फ। लेकिन 'मैं, अर्थात् (स्वयं) में इसका अर्थ क्या है,' func_globals (selector) ['this'] 'के मान को सेट करने के लिए यह एक लूप क्यों होगा? –

+0

खैर, गणना एक पुनरावृत्ति के बाहर [(अनुक्रमणिका, तत्व)] का अनुक्रम बनाता है (और PyQuery क्लास 'सूची' के उप-वर्ग के रूप में पुनरावर्तनीय है)। इसलिए, 'i' एक तत्व का सूचकांक है और' यह 'PyQuery ऑब्जेक्ट में संग्रहीत तत्व को संदर्भित करता है। यह समझने का सबसे अच्छा तरीका है कि PyQuery गहराई से कैसे काम करता है, अपने कोड में गोता लगाने के लिए है। –

-2

यह एक NameError फेंक नहीं है।

>>> f = lambda i: some_non_named_var 
>>> f(1) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 1, in <lambda> 
NameError: global name 'some_non_named_var' is not defined 

उपर्युक्त त्रुटि तब तक त्रुटि नहीं करता जब तक आप उस कार्य को कॉल न करें जिसे आपने छीन लिया है। आपके द्वारा दिखाए गए उदाहरण कोड में, वे लैम्ब्डा selector फ़ंक्शन को कॉल करने से पहले func_globals में this नामक एक चर सेट कर रहे हैं।

+0

यह क्यों कम किया जा रहा है? यह कुछ अन्य उत्तरों के रूप में पूर्ण नहीं हो सकता है, लेकिन यह अभी भी दिखाता है कि क्या हो रहा है .. –

1

दूसरों ने सही ढंग से बताया है कि this उस लैम्ब्डा के अंदर परिभाषित किया गया है जिसके बारे में आप बात कर रहे हैं।

में थोड़ा और अधिक विस्तृत करने के लिए निम्न कोड आजमा कर देखें:

>>> def f(): 
...  print f_global 
... 
>>> f() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 2, in f 
NameError: global name 'f_global' is not defined 
>>> f.__globals__['f_global'] = "whoa!!" #Modify f()'s globals. 
>>> f() 
whoa!! 

यह ठीक है कि वहाँ क्या हो रहा है। On line 496, you would see the following code:

for i, this in enumerate(self):    #this is the current object/node. 
    func_globals(selector)['this'] = this #func_globals returns selector.__globals__ 
संबंधित मुद्दे