2012-04-04 21 views
7

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

def memoize(f): 
    cache= {} 
    def memf(*x): 
     if x not in cache: 
      cache[x] = f(*x) 
     return cache[x] 
    return memf 

@memoize 
def fib(n): 
    if n==1 or n==0: 
     return 1 
    return fib(n-2) + fib(n-1) 

print fib(969) 

आंतरिक कार्यकलापों को थोड़ा बेहतर समझना पसंद है, मुझे पाइथन में सजावटी या पैरामीटर हैंडलिंग पर पढ़ने से जवाब नहीं मिला है।

सजाए गए फ़ंक्शन को हर बार कैश शब्दकोश को फिर से शुरू क्यों नहीं किया जाता है?

* x को सजाए गए फ़ंक्शन को भेजा गया पैरामीटर कैसे माना जाता है, यानी 9 6 9 फ़ंक्शन कॉल फ़िब (9 6 9) में?

उत्तर

9

सजावटी समारोह को पहली बार परिभाषित करने के तुरंत बाद सजावटी को केवल एक बार बुलाया जाता है। इस प्रकार, इन दो तकनीकों (@wrap और बार = चादर (पट्टी) का प्रयोग करके) एक ही हैं:

>>> def wrap(f): 
...  print 'making arr' 
...  arr = [] 
...  def inner(): 
...   arr.append(2) 
...   print arr 
...   f() 
...  return inner 
...  
>>> @wrap 
... def foo(): 
...  print 'foo was called' 
...  
making arr 
>>> foo() 
[2] 
foo was called 
>>> foo() 
[2, 2] 
foo was called 
>>> def bar(): 
...  print 'bar was called' 
...  
>>> bar = wrap(bar) 
making arr 
>>> bar() 
[2] 
bar was called 

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

सजाए गए फ़ंक्शन में तर्क पारित करने के मामले में, याद रखें कि एक सजावटी फ़ंक्शन पैरामीटर के रूप में लेता है और उस फ़ंक्शन का एक संशोधित संस्करण देता है। तो एक सजावट आम तौर पर एक पैरामीटर लेता है, जो वह कार्य है जो इसे संशोधित कर रहा है। यह एक नया फ़ंक्शन देता है, और सजावटी उस फ़ंक्शन को परिभाषित कर सकता है जो इसे किसी भी तर्क (उदाहरण के लिए, * तर्क) लेने के रूप में लौटाता है। सजावटी एक ऐसा फ़ंक्शन भी वापस कर सकता है जो उस विधि के लिए बहुत से पैरामीटर लेता है जो इसे सजाने के लिए करता है।

>>> def wrap_with_arg(f): 
...  def wrap(*args): 
...   print 'called with %d arguments' % len(args) 
...   f(args) 
...  return wrap 
...  
>>> @wrap_with_arg 
... def baz(arg): 
...  print 'called with argument %r' % arg 
...  
>>> baz(3) 
called with 1 arguments 
called with argument 3 
>>> baz(3, 4) 
called with 2 arguments 
Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
    File "<input>", line 4, in wrap 
    File "<input>", line 3, in baz 
TypeError: not all arguments converted during string formatting 

अंततः baz एक त्रुटि फेंकता है, ध्यान दें कि किस तर्क की संख्या सही ढंग से पहले त्रुटि फेंक दिया जाता है छपा है।

+0

+1 शानदार उत्तर। –

+1

+1 भी, यह उल्लेख करना दिलचस्प होगा कि एक बंद किया जा रहा है और इसलिए 'cache' तक पहुंचना संभव है जब फ़ंक्शन' defm' पहले से ही वापस कर दिया गया हो। – mmarinero

+0

धन्यवाद, अब मैं सजावटी को बहुत बेहतर समझता हूं! :) –

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