2009-06-05 18 views
5

क्या जेनरेटर ऑब्जेक्ट पर एक विशेषता बनाना संभव है?पायथन: जेनरेटर ऑब्जेक्ट पर गुण

यहाँ एक बहुत ही सरल उदाहरण है:

def filter(x): 
    for line in myContent: 
     if line == x: 
      yield x 

अब कहते हैं कि मैं इन फिल्टर जनरेटर का एक बहुत चारों ओर चल वस्तुओं है ... शायद उनमें से कुछ अनाम हैं ... मैं बाद में वापस जाने के लिए और पूछताछ करना चाहते हैं वे किसके लिए फ़िल्टर कर रहे हैं के लिए। क्या कोई तरीका है जो मैं कर सकता हूं) एक्स या बी के मान के लिए जनरेटर ऑब्जेक्ट से पूछताछ करें) x के मान के साथ एक विशेषता सेट करें जिसे मैं बाद में पूछताछ कर सकता हूं?

धन्यवाद

उत्तर

6

दुर्भाग्य से, जनरेटर वस्तुओं (परिणाम एक जनरेटर समारोह बुला से लौटे) मनमाना विशेषताएं जोड़ना समर्थन नहीं करते। आप जनरेटर ऑब्जेक्ट्स द्वारा अनुक्रमित बाहरी निर्देश का उपयोग करके कुछ हद तक इसके आसपास काम कर सकते हैं, क्योंकि ऐसी वस्तुओं एक धक्का में चाबी के रूप में प्रयोग योग्य हैं। तो जहां चाहते हैं ऐसा करने के लिए, कहते हैं:

a = filter(23) 
b = filter(45) 
... 
a.foo = 67 
... 
x = random.choice([a,b]) 
if hasattr(x, 'foo'): munge(x.foo) 

आप के बजाय कर सकते हैं:

foos = dict() 
a = filter(23) 
b = filter(45) 
... 
foos[a] = 67 
... 
x = random.choice([a,b]) 
if x in foos: munge(foos[x]) 

अधिक सजावटी कुछ भी के लिए, एक जनरेटर (एक या अधिक के बजाय एक वर्ग का उपयोग वर्ग के तरीकों जेनरेटर हो सकता है, सब के बाद)।

16

हां।

class Filter(object): 
    def __init__(self, content): 
     self.content = content 
    def __call__(self, someParam): 
     self.someParam = someParam 
     for line in self.content: 
      if line == someParam: 
       yield line 
2

नहीं। आप जेनरेटर पर मनमानी विशेषताओं को सेट नहीं कर सकते हैं।

एस लोट बताते हैं के रूप में, आप एक वस्तु हो सकता है एक जनरेटर की तरह, और कृत्यों एक जनरेटर की तरह दिखता है। और यदि यह एक बतख की तरह दिखता है, और एक बतख की तरह काम करता है, तो आप खुद को बतख टाइपिंग की बहुत परिभाषा प्राप्त कर चुके हैं।

यह उचित प्रॉक्सी विधियों के बिना gi_frame जैसे जेनरेटर विशेषताओं का समर्थन नहीं करेगा।

0

समस्या के बारे में सोचते हुए, जेनरेटर गुणों के एक सेट के आसपास ले जाने का एक तरीका है। यह थोड़ा पागल है - मैंने इसके बजाय एलेक्स मार्टेलि के सुझाव की दृढ़ता से सिफारिश की - लेकिन यह कुछ स्थितियों में उपयोगी हो सकती है।

my_content = ['cat', 'dog days', 'catfish', 'dog', 'catalog'] 

def filter(x): 
    _query = 'I\'m looking for %r' % x 

    def _filter(): 
     query = yield None 
     for line in my_content: 
      while query: 
       query = yield _query 

      if line.startswith(x): 
       query = yield line 

     while query: 
      query = yield _query 

    _f = _filter() 
    _f.next() 
    return _f 

for d in filter('dog'): 
    print 'Found %s' % d 

cats = filter('cat') 
for c in cats: 
    looking = cats.send(True) 
    print 'Found %s (filter %r)' % (c, looking) 

आप जनरेटर यह क्या पर फ़िल्टरिंग है पूछना चाहते हैं, सिर्फ इतना है कि सही का आकलन एक मूल्य के साथ send कहते हैं। बेशक, यह कोड आधा से शायद चालाक है। सावधानी से प्रयोग करें।

3

आप डिबगिंग उद्देश्यों के लिए उन्हें पूछताछ करना चाहते हैं, उसके बाद निम्न समारोह में मदद मिलेगी:

import inspect 

def inspect_generator(g): 
    sourcecode = open(g.gi_code.co_filename).readlines() 
    gline = g.gi_code.co_firstlineno 
    generator_code = inspect.getblock(sourcecode[gline-1:]) 

    output = "Generator %r from %r\n" % (g.gi_code.co_name, g.gi_code.co_filename) 
    output += "".join("%4s: %s" % (idx+gline, line) for idx, line in enumerate(generator_code)) 

    output += "Local variables:\n" 
    output += "".join("%s = %r\n" % (key,value) for key,value in g.gi_frame.f_locals.items()) 

    return output 

print inspect_generator(filter(6)) 
"""Output: 
Generator 'filter' from 'generator_introspection.py' 
    1: def filter(x): 
    2:  for line in myContent: 
    3:   if line == x: 
    4:    yield x 
Local variables: 
x = 6 
""" 

आप उन्हें पूछताछ तो इटरेटर प्रोटोकॉल को लागू करने कक्षाएं कार्यक्षमता लागू करना चाहते हैं शायद एक बेहतर विचार कर रहे हैं।

0

मुझे पता है यह एक बहुत ही देर से लिया गया जवाब है, लेकिन ..., अपने कोड सकता है बाद में सिर्फ जनरेटर के चर (रों) का निरीक्षण किया, का उपयोग करते हुए:

filter.gi_frame.f_locals

मुझे लगता है कि चींटियों आसमा कि की ओर संकेत किया।

+0

मैंने जेनरेटर के चर का निरीक्षण करने के लिए आपके सुझाव की कोशिश की। यह अभी तक काम करता है क्योंकि 'स्टॉपइटरेशन' अभी तक नहीं पहुंचा है। उसके बाद, 'gi_frame' 'none' बन जाता है। – bli

संबंधित मुद्दे