10

में बेहतर फ़ंक्शन संरचना मैं पाइथन में काम करता हूं। हाल ही में, मैंने fn नामक एक अद्भुत छोटे पैकेज की खोज की। मैं इसे फ़ंक्शन संरचना के लिए उपयोग कर रहा हूं।पायथन

उदाहरण के लिए, के बजाय:

baz(bar(foo(x)))) 
fn साथ

, आप लिख सकते हैं:

(F() >> foo >> bar >> baz)(x) . 

जब मैं इसे देखा, मैं तुरंत Clojure के बारे में सोचा:

(-> x foo bar baz) . 

लेकिन ध्यान दें, क्लोजर में, इनपुट बाईं ओर है। मुझे आश्चर्य है कि यह पाइथन/एफएन में संभव है।

+2

जबकि ऑपरेटर व्यवहार अधिक भार दिलचस्प है, मेरे लिए यह सिर्फ एक बुरी बात वास्तविक कोड में करने के लिए की तरह लगता है। –

+0

पाइथन में उस सटीक वाक्यविन्यास कार्य को करने का कोई तरीका नहीं है, अगर आप यही पूछ रहे हैं। आप इसे विभिन्न तरीकों से अनुमानित करने में सक्षम हो सकते हैं। वाक्यविन्यास के अनुसार आपके लिए वास्तव में क्या महत्वपूर्ण है? – BrenBarn

+0

प्रवाह को बाएं से दाएं रखें।वर्तमान में, रचना समारोह के लिए तर्क अंत में है। अगर मैं एफ() >> एक्स >> foo >> बार >> बाज़, या इसी तरह लिख सकता हूं तो यह स्पष्ट होगा। –

उत्तर

9

आप सटीक सिंटैक्स को दोहराने नहीं कर सकते, लेकिन आप कुछ इसी तरह बना सकते हैं:

def f(*args): 
    result = args[0] 

    for func in args[1:]: 
     result = func(result) 

    return result 

काम करने के लिए लगता है:

>>> f('a test', reversed, sorted, ''.join) 
' aestt' 
2

आपको लगता है कि सटीक सिंटैक्स नहीं मिल सकता है, हालांकि आप कर सकते हैं F(x)(foo, bar, baz) जैसे कुछ प्राप्त करें।

class F(object): 
    def __init__(self, arg): 
     self.arg = arg 

    def __call__(self, *funcs): 
     arg = self.arg 
     for f in funcs: 
      arg = f(arg) 
     return arg 

def a(x): 
    return x+2 
def b(x): 
    return x**2 
def c(x): 
    return 3*x 

>>> F(2)(a, b, c) 
48 
>>> F(2)(c, b, a) 
38 

इस ब्लेंडर के जवाब से थोड़ी अलग है, क्योंकि यह तर्क, जो बाद में विभिन्न कार्यों के साथ फिर से इस्तेमाल किया जा सकता संग्रहीत करता है: यहाँ एक सरल उदाहरण है।

यह सामान्य फ़ंक्शन एप्लिकेशन के विपरीत की तरह है: फ़ंक्शन को आगे बढ़ाने और कुछ तर्कों को बाद में निर्दिष्ट करने के बजाय, आप तर्क निर्दिष्ट करते हैं और फ़ंक्शन को बाद में निर्दिष्ट करने के लिए छोड़ देते हैं। यह एक दिलचस्प खिलौना है लेकिन यह सोचना मुश्किल है कि आप वास्तव में यह क्यों चाहते हैं।

1

आप एक छोटे से हैक साथ fn उपयोग करने के लिए, आप थोड़ा Clojure वाक्य रचना के करीब प्राप्त कर सकते हैं चाहते हैं:

>>> def r(x): return lambda: x 
>>> (F() >> r(x) >> foo >> bar >> baz)() 

देखें कि कैसे मैं रचना श्रृंखला की शुरुआत है कि बस वापस आ जाएगी x में एक और समारोह जोड़ा जब बुलाया जाता है। इसके साथ समस्या यह है कि आपको अभी भी किसी भी तर्क के बिना, अपने रचना किए गए फ़ंक्शन को कॉल करना होगा।

मुझे लगता है कि @ ब्लेंडर का जवाब पाइथन में क्लोजर के थ्रेड फ़ंक्शन को अनुकरण करने का प्रयास करने का सबसे अच्छा शर्त है।

0

मैं इस

def _composition(arg, *funcs_and_args): 
    """ 
    _composition(
     [1,2,3], 
     (filter, lambda x: x % 2 == 1), 
     (map, lambda x: x+3) 
    ) 
    #=> [4, 6] 
    """ 
    for func_and_args in funcs_and_args: 
     func, *b = func_and_args 
     arg = func(*b, arg) 
    return(arg) 
0

यह सरल इनपुट के लिए काम करने के लिए लगता है के साथ आया था। सुनिश्चित नहीं है कि जटिल इनपुट के लिए प्रयास के लायक है, उदाहरण के लिए, ((42, 'spam'), {'spam': 42})

def compose(function, *functions): 
    return function if not functions else \ 
      lambda *args, **kwargs: function(compose(*functions)(*args, **kwargs)) 

def rcompose(*functions): 
    return compose(*reversed(functions)) 

def postfix(arg, *functions): 
    return rcompose(*functions)(arg) 

उदाहरण:

>>> postfix(1, str, len, hex) 
'0x1' 
>>> postfix(1, hex, len) 
3