2011-08-18 13 views
9

मैं एक डेकोरेटर कि एक तर्क के रूप उदाहरण ही आवश्यकता है का उपयोग कर उदाहरण के तरीकों को सजाने के लिए निम्न कोड के साथ आया था:पायथन: कुछ भी उदाहरण के रूप में गतिशील रूप से बताए उदाहरण के तरीकों के साथ गलत विशेषताओं

from functools import wraps 

def logging_decorator(tricky_instance): 
    def wrapper(fn): 
     @wraps(fn) 
     def wrapped(*a, **kw): 
      if tricky_instance.log: 
       print("Calling %s.." % fn.__name__) 
      return fn(*a, **kw) 
     return wrapped 
    return wrapper  

class Tricky(object): 
    def __init__(self, log): 
     self.log = log 
     self.say_hi = logging_decorator(self)(self.say_hi) 

    def say_hi(self): 
     print("Hello, world!") 


i1 = Tricky(log=True) 
i2 = Tricky(log=False) 

i1.say_hi() 
i2.say_hi() 

यह महान काम करने के लिए लगता है , लेकिन मुझे डर है कि मैंने इस चाल के कुछ अनपेक्षित साइड इफेक्ट्स को अनदेखा कर दिया होगा। क्या मैं खुद को पैर में शूट करने वाला हूं, या यह सुरक्षित है?

ध्यान दें कि मैं नहीं है वास्तव में प्रवेश के लिए इसका उपयोग करना चाहते हैं, यह सिर्फ कम से कम सार्थक उदाहरण मैं के साथ आ सकता है।

+0

कानूनी लगता है: एक शर्मनाक सरल समाधान हो रहा है। IMHO। – Evpok

उत्तर

2

मुझे लगता है कि मैं बेकार में स्मार्ट बनने की कोशिश कर रहा था।

from functools import wraps 

def logging_decorator(fn): 
    @wraps(fn) 
    def wrapped(self, *a, **kw): 
     if self.log: 
      print("Calling %s.." % fn.__name__) 
     return fn(self, *a, **kw) 
    return wrapped 

class Tricky(object): 
    def __init__(self, log): 
     self.log = log 

    @logging_decorator 
    def say_hi(self): 
     print("Hello, world!") 

i1 = Tricky(log=True) 
i2 = Tricky(log=False) 

i1.say_hi() 
i2.say_hi() 
4

यह वास्तव में मेरे लिए स्पष्ट नहीं है क्यों आप कभी भी ऐसा करना चाहते हैं जाएगा। यदि आप एक नई विधि प्रकार प्रदान करना चाहते हैं गतिशील types का उपयोग करें:

import types 

class Tricky(object): 
    def __init__(self): 
     def method(self): 
      print('Hello') 
     self.method = types.MethodType(method, self) 

आप उदाहरण के साथ कुछ करना चाहते हैं, यह __init__ विधि में करते हैं।

def decorator(tricky_instance): 
    def wrapper(meth): 
     print(meth.im_self == tricky_instance) 
     return meth 
    return wrapper 

व्यक्तिगत रूप से, मुझे लगता है कि यह हो सकता है कि-मैं-नहीं करना चाहिए-उपयोग-डेकोरेटर भूमि में खड़ा है: तुम सिर्फ डेकोरेटर के अंदर विधि के उदाहरण पर पहुंच चाहते हैं, तो आप im_self विशेषता का उपयोग कर सकते हैं।

+0

मैं अपवादों द्वारा संकेतित, अस्थायी) नेटवर्क समस्याओं पर आवृत्ति विधियों को स्वचालित रूप से याद करना चाहता हूं। कौन से अपवाद अस्थायी हैं और जो स्थायी हैं, वास्तविक उदाहरण पर निर्भर करते हैं (उदाहरण अमेज़ॅन एस 3 वस्तुओं का प्रतिनिधित्व करते हैं जिनकी स्थिरता गारंटी भंडारण स्थान पर निर्भर करती है)। – Nikratio

+0

मुझे समझ में नहीं आता कि आपका कोड क्या करता है/अच्छा है। क्या आप विस्तारित कर सकते हैं? – Nikratio

+1

मेरा कोड '__init__' में एक नई आवृत्ति विधि बनाता है। मुझे लगता है कि आप एक सजावट लिखने की कोशिश कर रहे हैं, और आप चाहते हैं कि सजावटी को सजाए जाने वाले तरीके के उदाहरण के लिए सजावट हो, सजावट को सामान्यीकृत करने के लिए? – zeekay

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