2011-08-14 25 views
8

पाइथन नोब के भीतर किसी फ़ंक्शन तक पहुंचना। मैं 'fib' फ़ंक्शन के भीतर 'आंतरिक' फ़ंक्शन को कैसे पकड़ूं?फ़ंक्शन (नेस्टेड फ़ंक्शन?)

from time import sleep 

class Fibonacci(object): 

    def __init__(self, a, b, limit=50): 
     self.a = a 
     self.b = b 
     self.limit = limit 

    def fib(self): 

     while self.a < self.limit: 
      c = self.a + self.b 
      sleep(1) 
      print self.a, 
      self.b = self.a 
      self.a = c 

     def inner(self): 
      print 'Damn it! Just print already!' 


j = Fibonacci(0,1,2) 
j.fib() 

## This doesn't work. Gives an "AttibuteError: 'function' object has no attribute 'inner'" 
j.fib.inner() 
+1

मेरे अजगर जंग लगी है लगता है, लेकिन मैं बहुत यकीन है कि आप 'fib' के बाहर से inner' उपयोग नहीं कर सकते' हूँ, बदलते कैसे 'inner' बिना परिभषित किया। –

+1

seykom, आपको अपने अधिक प्रश्नों के उत्तर स्वीकार करने की आवश्यकता है। उस उत्तर के बगल में स्थित चेक मार्क पर क्लिक करें जिसने आपको सबसे अधिक मदद की। आपको इसे अपने पुराने प्रश्नों के साथ-साथ नए लोगों के लिए भी करना चाहिए। – agf

+0

आपको ऐसा करने की आवश्यकता क्यों है? क्या आपने केवल कार्यों को घोंसला नहीं माना है? खासतौर से चूंकि 'आंतरिक' के लिए इंटरफ़ेस ऐसा लगता है कि आप इसे 'फाइबोनैकी' ऑब्जेक्ट का एक तरीका बनना चाहते हैं ... यह वास्तव में एक आंतरिक फ़ंक्शन के रूप में काम नहीं करेगा ... –

उत्तर

11

आप नहीं कर सकते हैं, fib रिटर्न inner किसी भी तरह जब तक नहीं। inner अनिवार्य रूप से fib के दायरे के अंदर एक स्थानीय चर है और आप इसके बाहर से किसी फ़ंक्शन के स्थानीय लोगों तक नहीं पहुंच सकते हैं। (यह भी समझ में नहीं आता है, क्योंकि जब फ़ंक्शन चल रहा है, तो स्थानीय लोग मौजूद नहीं हैं। इसके बारे में सोचें - क्या यह fib के c फ़ंक्शन के बाहर से वैरिएबल तक पहुंचने के लिए समझ में आता है?)

+0

मैं देखता हूं। धन्यवाद!!! – kassold

1

जैसा कि कुछ अन्य पाठकों ने बताया है, यह गुंजाइश की समस्या है। Fwiw, इस आंतरिक समारोह वापस लौट कर काम करता है:

from time import sleep 

class Fibonacci(object): 

    def __init__(self, a, b, limit=50): 
     self.a = a 
     self.b = b 
     self.limit = limit 

    def fib(self): 

     while self.a < self.limit: 
      c = self.a + self.b 
      sleep(1) 
      print self.a, 
      self.b = self.a 
      self.a = c 

     def inner(): 
      print 'Damn it! Just print already!' 

     return inner 


j = Fibonacci(0,1,2) 
j.fib()() 

संदर्भ के लिए, अजगर की scoping के लिए एक अच्छा परिचय है:

Short Description of the Scoping Rules?

+0

धन्यवाद। 'आंतरिक' – kassold

+0

में 'स्वयं' की आवश्यकता क्यों नहीं है क्योंकि 'आंतरिक' कक्षा के उदाहरण की विधि नहीं है। – kindall

+0

क्योंकि ऑब्जेक्ट (जे) पर भीतरी नहीं कहा जा रहा है, आंतरिक अकेले स्टैंड के रूप में वापस किया जा रहा है। दूसरे शब्दों में, आंतरिक फाइबोनैकी कक्षा का एक तरीका नहीं है, यह केवल एक स्टैंड स्टैंड है। –

7

निम्नलिखित प्रयोग न करें।

[...] 
>>> j = Fibonacci(0,1,2) 
>>> j.fib() 
0 1 1 
>>> # dark magic begins! 
>>> import new 
>>> new.function(j.fib.im_func.func_code.co_consts[2],{})(None) 
Damn it! Just print already! 

आप बस कि यह वास्तव में अजगर नहीं है की ओर देखकर उसे बता सकते हैं, और यह वास्तव में बुला नहीं है उस बात के लिए "आंतरिक" खुद समारोह, यह बस ऐसा लगता है जैसे एक नया कार्य बनाने है। मैंने ग्लोबल्स को सही तरीके से सेट करने से भी परेशान नहीं किया, क्योंकि यह पहली जगह में करने के लिए एक भयानक बात है ..

[मुझे यह उल्लेख करना चाहिए कि उपर्युक्त बिंदु यह ध्यान रखना है कि आप यह विचार कर सकते हैं कि आप बाहर से आंतरिक प्रवेश नहीं करना सख्ती से सच नहीं है, हालांकि यह लगभग कभी भी एक अच्छा विचार नहीं है। अपवादों में दुभाषिया-स्तर कोड निरीक्षण, आदि शामिल हैं]

अस्पष्ट! अशुद्ध!

+0

के लिए धन्यवाद बेशक, सामान्य मामले में आपको 'co_consts' में सही इंडेक्स को समझने के लिए डिस्सेबलर और/या बड़ी मात्रा में मस्तिष्क शक्ति और/या परीक्षण और त्रुटि का उपयोग करने की आवश्यकता होगी। .. –

+0

आपको 'type.FunctionType' का उपयोग करना चाहिए :) – schlamar

+0

धन्यवाद! जब आप स्वयं कोड को नियंत्रित करते हैं तो एक भयानक चीज होती है, लेकिन यह किसी और के फ़ंक्शन को डीबग करने में मददगार हो सकती है। –

5
from time import sleep 

class Fibonacci(object): 

    def __init__(self, a, b, limit=50): 
     self.a = a 
     self.b = b 
     self.limit = limit 

    def fib(self): 

     while self.a < self.limit: 
      c = self.a + self.b 
      sleep(1) 
      print self.a, 
      self.b = self.a 
      self.a = c 

     def inner(self): 
      print 'Damn it! Just print already!' 
     Fibonacci.fib.inner = inner 

    fib.inner = None 

यह कोड स्निपेट आपको आंतरिक उपयोग करने की अनुमति देगा।

4

नीचे प्राप्त करने के लिए आप क्या चाहते हैं

from types import CodeType, FunctionType 

def find_nested_func(parent, child_name): 
    """ Return the function named <child_name> that is defined inside 
     a <parent> function 
     Returns None if nonexistent 
    """ 
    consts = parent.func_code.co_consts 
    for item in consts: 
     if isinstance(item, CodeType) and item.co_name==child_name: 
      return FunctionType(item, globals())