2012-02-08 15 views
9

मैं एक ऑब्जेक्ट विधि के स्थानीय मूल्य को एक सजावटी से पढ़ना चाहता हूं जो इसे लपेटता है। मुझे सजावट के भीतर से फ़ंक्शन और func_code तक पहुंच प्राप्त हुई है, लेकिन ऐसा लगता है कि मैं इसे बाहर निकाल सकता हूं स्थानीय वार्स के नाम हैं, लेकिन उनके मूल्य नहीं हैं।पायथन: क्या एक सजावट के भीतर से स्थानीय फ़ंक्शन वैरिएबल प्राप्त करने का कोई तरीका है जो इसे लपेटता है?

क्या यह संभव है? (जो अगर सजाया समारोह निवासी है टूट जाएगा) समारोह के internals के साथ लगभग नगण्य की

उत्तर

7

https://stackoverflow.com/a/4249347/224295 देखें, http://code.activestate.com/recipes/577283-decorator-to-expose-local-variables-of-a-function-/

कार्य उदाहरण:

import sys 

class persistent_locals(object): 
    def __init__(self, func): 
     self._locals = {} 
     self.func = func 

    def __call__(self, *args, **kwargs): 
     def tracer(frame, event, arg): 
      if event=='return': 
       self._locals = frame.f_locals.copy() 

     # tracer is activated on next call, return or exception 
     sys.setprofile(tracer) 
     try: 
      # trace the function call 
      res = self.func(*args, **kwargs) 
     finally: 
      # disable tracer and replace with old one 
      sys.setprofile(None) 
     return res 

    def clear_locals(self): 
     self._locals = {} 

    @property 
    def locals(self): 
     return self._locals 

@persistent_locals 
def func(): 
    local1 = 1 
    local2 = 2 

func() 
print func.locals 
+0

काम करता है। मैं पहले स्थान पर इसके बारे में एक बुरा विचार मानता हूं लेकिन मुझे यह देखने में दिलचस्पी थी कि यह संभव है या नहीं। – Harel

+0

ग्रेट चाल। मैं एक डीबगर कर रहा हूं जिसे एक सजाए गए समारोह से चुपके से आंतरिक पकड़ लेना है और इसके लिए यह वैध रूप से उपयोगी है। ध्यान देने योग्य बात यह है कि ट्रैसर() को सजाए गए फ़ंक्शन की वापसी पर ही नहीं, बल्कि उस फ़ंक्शन के भीतर से जुड़े सभी कार्यों के रिटर्न पर भी कहा जाता है। चूंकि सजाए गए कार्य में हमेशा अंतिम वापसी होती है, (और इसलिए अंतिम बार _locals सेट करता है) इससे कोई फर्क नहीं पड़ता। – Peter

-2

इसके बजाय, अपने स्वयं के आवरण बारे में इस तरह:

def myDecorator(f): 
    def wrapper(*args, **kwargs): 
    print('Arguments to this function %r/%r' % (args, kwargs)) 
    return f(*args, **kwargs) 
    return wrapper 
3

<edit> मैं सिर्फ महसूस किया कि मैं सवाल पढ़ने में भूलना और कि आप फ़ंक्शन विशेषताएँ प्राप्त करने की कोशिश नहीं कर रहे हैं, लेकिन फ़ंक्शन से स्थानीय चर मान। आप जो करना चाहते हैं वह संभव नहीं है क्योंकि फ़ंक्शन चलाने तक उन स्थानीय चर नहीं बनाए जाते हैं, और फ़ंक्शन के लिए स्थानीय दायरा हटा दिया जाता है जैसे ही फ़ंक्शन लौटाता है या अपवाद उठाता है।

मैं अपना मूल उत्तर छोड़ रहा हूं क्योंकि आप संभावित रूप से स्थानीय चर के बजाय विशेषताओं का उपयोग करने के लिए अपने फ़ंक्शन को फिर से लिख सकते हैं और अभी भी इस सजावट का उपयोग प्रभावी ढंग से करने के लिए कर सकते हैं।

आपके द्वारा वर्तमान में प्रयास किए जाने वाले पोस्ट को पोस्ट करना उपयोगी होगा और कुछ उदाहरण अपेक्षित आउटपुट के साथ कॉल करेंगे यदि यह सही तरीके से काम कर रहा था। </edit>

जब आपको विशेषताओं के साथ फ़ंक्शन की आवश्यकता होती है, तो आमतौर पर सामान्य फ़ंक्शन परिभाषा के बजाय कॉल करने योग्य वर्ग का उपयोग करना एक अच्छा विचार है।

यहाँ, एक डेकोरेटर जहां आवरण एक प्रतिदेय वर्ग है, जो डेकोरेटर आसानी से चर का उपयोग करने की अनुमति देता है का एक उदाहरण है, क्योंकि वे आवरण वर्ग के उदाहरण चर हैं:

def deco(func): 
    class Wrapper(object): 
     def __init__(self): 
      self.foo = None 
     def __call__(self, *args): 
      print 'old foo:', self.foo 
      result = func(*args) 
      print 'new foo:', self.foo 
      return result 
    return Wrapper() 

@deco 
def my_func(new_foo): 
    my_func.foo = new_foo 

कौन सा my_func व्यवहार में जो परिणाम इस तरह:

>>> my_func('test') 
old foo: None 
new foo: test 
>>> my_func.foo 
'test' 
>>> my_func(42) 
old foo: test 
new foo: 42 
>>> my_func.foo 
42 
-1

नहीं, यह लिपटे समारोह के अंदर चर तक पहुँचने के लिए है, क्योंकि (जैसा कि एफजे उसके संपादित में बताया) वे समय डेकोरेटर दायरे में है पर मौजूद नहीं है संभव नहीं है।

5

जो आप पूछ रहे हैं वह वास्तव में समझ में नहीं आता है।

एक फ़ंक्शन के स्थानीय चर के पास हर समय मूल्य नहीं होते हैं।

def foo(x): 
    y = x + 27 
    return y 

foo के स्थानीय चर y का मूल्य क्या है: इस समारोह पर विचार करें? आप जवाब नहीं दे सकते हैं, जब तक आप foo पर कॉल नहीं करते हैं तब तक सवाल तब तक समझ में नहीं आता है (और फिर भी, जब तक कि y = x + 27 निष्पादित नहीं किया जाता है)।

और फिर भी यह है कि अभी y इस समय एक मूल्य नहीं हो सकता नहीं है, वहाँ "उड़ान" foo के लिए सजा के किसी भी संख्या हो सकता है। foo निष्पादित धागे हो सकते हैं, या foo रिकर्सिव (संभावित रूप से परोक्ष रूप से) हो सकता है ताकि एक कॉल कॉल में भी एक से अधिक कॉल प्रगति पर हो। या foo जनरेटर हो सकता है, इसलिए रिकर्सन के बिना भी कई उड़ानें foo निष्पादन हो सकती हैं (यानी।वे सभी बाहरीतम foo दायरे से पहुंच योग्य नहीं हैं)। तो क्या आपको y का मूल्य मिलेगा?

foo में y का मूल्य सिर्फ एक अच्छी तरह से परिभाषित अवधारणा जब तक आप foo के दायरे के भीतर के बारे में बात कर रहे हैं नहीं है।


अजगर के लचीलेपन को देखते हुए, मैं बहुत यकीन है कि यह स्टैक फ्रेम आत्मनिरीक्षण करते हैं और foo के लिए एक ढेर फ्रेम को खोजने के लिए संभव है जब है कोई भी वर्तमान रहते हैं और उस समय उसके स्थानीय चरों के मान को बाहर खींच रहा हूँ। यह एक सजावटी के साथ करने के लिए बहुत कठिन (यदि असंभव नहीं है), क्योंकि (foo जनरेटर नहीं है) सजावट केवल foo "रैपर कोड" को जोड़ सकता है, जिसका अर्थ है कि सजावटकर्ता द्वारा नियंत्रित कोड foo रनों के पहले और बाद में चलता है , इसलिए आपको केवल नियंत्रण प्राप्त होता है जब foo का स्टैक फ्रेम मौजूद नहीं होता है।

मैं विशिष्ट बिंदुओं को बिल्कुल ठीक करने के लिए नहीं कहूंगा, क्योंकि मुझे नहीं पता कि यह कैसे करना है। ऐसा लगता है कि यह लगभग निश्चित रूप से एक बुरा विचार है, जब तक कि आप एक डीबगर लिख रहे हों।

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

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