2010-11-04 10 views
8

मैंने पूरी तरह से देखा है लेकिन बिना किसी शोर के खोजना कठिन विषय है।फ़ंक्शन कैसे जोड़ें

def f(arg): 
    return arg * arg 

def add(self, other): 
    return self * other 

f.__add__ = add 

cubefunction = f + f 

लेकिन मैं काम पर त्रुटियों की तरह cubefunction के लिए मिलता है:

TypeError: unsupported operand type(s) for +: 'function' and 'function' 

वहाँ कोई समारोह बीजगणित अजगर में संभव है या मैं सिर्फ एक गूंगा गलती कर रहा हूँ मैं कुछ इस तरह करना चाहते हैं?

संपादित करें: बहुत बाद में, मैं कार्यात्मक प्रोग्रामिंग (http://docs.python.org/howto/functional.html) करने के लिए अजगर की आधिकारिक परिचय पढ़ रहा था, और नीचे की ओर यह एक तीसरी पार्टी पैकेज "कार्यात्मक" (http://oakwinter.com/code/functional/documentation/) है, जो कार्यों की रचना कर सकते हैं, यानी संदर्भ:

>>> from functional import compose 
>>> def add(a, b): 
...  return a + b 
... 
>>> def double(a): 
...  return 2 * a 
... 
>>> compose(double, add)(5, 6) 
22 
+0

हालांकि, आपका उदाहरण इंगित करता है कि आप चौथी शक्ति के लिए मूल्य बढ़ाना चाहते हैं, इसे क्यूब नहीं करें। –

+0

मुझे कल्पना है कि + "गोफ" संरचना कार्य करने के लिए है? (यह फ़ंक्शन ऑब्जेक्ट पर * ओवरलोडिंग + के उत्तर के साथ मदद नहीं करता है *)। –

+0

ओह, मेरा मतलब है '(एफ + जी) (एक्स) ==> एफ (जी (एक्स))' ... वैसे भी, मैं यह सुनिश्चित करना चाहता हूं कि यह स्पष्ट है। एक मध्यवर्ती प्रकार/रैपर का उपयोग करने की तकनीक दिखाने वाला पहले से ही एक उत्तर है। –

उत्तर

6

मुझे नहीं लगता कि आप ऐसा कर सकते हैं। हालांकि, __call__ जादू पद्धति का उपयोग करके आप अपने खुद के प्रतिदेय वर्ग जो एक समारोह के रूप में कार्य करता है परिभाषित करने और जिस पर आप __add__ परिभाषित कर सकते हैं कर सकते हैं: संरचना के *

>>> class FunctionalFunction(object): 
...  def __init__(self, func): 
...    self.func = func 
... 
...  def __call__(self, *args, **kwargs): 
...    return self.func(*args, **kwargs) 
... 
...  def __add__(self, other): 
...    def summed(*args, **kwargs): 
...      return self(*args, **kwargs) + other(*args, **kwargs) 
...    return summed 
... 
...  def __mul__(self, other): 
...    def composed(*args, **kwargs): 
...      return self(other(*args, **kwargs)) 
...    return composed 
... 
>>> triple = FunctionalFunction(lambda x: 3 * x) 
>>> times_six = triple + triple 
>>> times_six(2) 
12 
>>> times_nine = triple * triple 
>>> times_nine(3) 
27 

यहाँ + pointwise इसके अलावा करने के लिए ओवरलोड हो गया है, और। बेशक, आप जो भी चाहें कर सकते हैं।


पायथन गुरु के लिए दिलचस्प सवाल: निम्नलिखित क्यों काम नहीं करते हैं (गंदी हैक हालांकि यह है)?

>>> from types import MethodType, FunctionType 
>>> f = lambda: None 
>>> f.__add__ = MethodType(lambda self, other: "summed!", f, FunctionType) 
>>> f.__add__(f) 
'summed!' 
>>> f + f 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for +: 'function' and 'function' 
+1

+1 मध्यवर्ती प्रकार और \ __ call__ का उपयोग करके दिखाए जाने के लिए +1। हालांकि, मुझे विश्वास है कि '(एफ + जी) (एक्स) ==> एफ (जी (एक्स)) '- वह है, कार्य संरचना। –

+1

@pst: हेह यह कुछ मामूली नोटेशन है। मैंने ओपी के लिए रचना में जोड़ा है। – katrielalex

+1

@pst हाँ, katriealex इसके बारे में बिल्कुल सही है। कार्य आमतौर पर एक अंगूठी के लिए लिया जाता है। '+' सार्वभौमिक रूप से बिंदुवार जोड़ है। '*' या तो बिंदुवार गुणा _or_ संरचना हो सकता है (जहां संभव हो)। – aaronasterling

1

मुझे लगता है कि तुम क्या करने का मतलब क्या है:

cubefunction = (lambda x: add(f(x), f(x))) 
+6

नहीं, मुझे लगता है कि वह क्या करने की कोशिश कर रहा है वह कार्यों पर '__add__' परिभाषित करता है। – katrielalex

1

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

1

ठीक है मुझे लगता है कि मुझे कार्यों को जोड़ने में कुछ दिलचस्प मिला है। यह लैम्ब्डा फ़ंक्शन के बारे में है और यह आपकी समस्या को ठीक कर सकता है।कम से कम यह मेरा तय:

>>> def func(x) : 
>>>  return x 
>>> 
>>> f = lambda x : func(x) 
>>> sum_of_f = [ f for i in range(5) ] 
>>> F = lambda x : sum([ i(x) for i in sum_of_f ]) 
>>> F(1) 
5 
>>> F(2) 
10 

और जो रुचि रखते हैं के लिए मानकों

>>> def func(x, p) : 
>>>  return x * p 
>>> 
>>> param = [ 0, 1, 2, 3, 4 ] 
>>> 
>>> f = lambda x, p : func(x, p) 
>>> sum_of_f = [ f for i in range(5) ] 
>>> F_bis = lambda x : sum([ sum_of_f[i](x, param[i]) for i in range(5) ]) 
>>> F_bis(1) 
10 
>>> F_bis(2) 
20 
1

थोड़ा देर से पारित करने के लिए है, लेकिन बीजगणित इस तरह लैम्ब्डा कार्यों का उपयोग कर आसानी से किया जा सकता है:

>>> f = lambda x: x*x 
>>> g = lambda x: x*x 
>>> h = lambda x: f(g(x)) 
>>> h(2) 
16 
>>> j = lambda x: f(x) + g(x) 
>>> j(2) 
8 
>>> 

(एफ और जी को लैम्ब्डा फ़ंक्शन होने की आवश्यकता नहीं है)

आप सभी प्रकार के कर सकते हैं इसके साथ दिलचस्प चीजों का। आइए मान लें कि आप दिए गए n के लिए फ़ंक्शन f(x) = 1 + x + x**2 + ... + x**n को परिभाषित करना चाहते हैं। आप कर सकते हैं: कारण है कि मैं लैम्ब्डा कि जिस तरह से (lambda x, j = i + 1, k = f:) बनाया

>>> n = 3 
>>> f = lambda x: 1 
>>> for i in range(n): 
...  f = lambda x, j = i + 1, k = f: k(x) + x**j 
... 
>>> f(2) 
15 

समझने के लिए इस पढ़ने के लिए बेहतर है: https://docs.python.org/3.5/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result

लंबी कहानी कम: एक लैम्ब्डा समारोह में पैरामीटर स्थानीय प्रतिलिपि की जरूरत नहीं है । अगर मैंने लूप से i का उपयोग lambda x, k = f: k(x) + x**(i + 1) में किया था, तो हमारे पास f(x) = 1 + x**3 + x**3 + x**3 फ़ंक्शन था।

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