मैं पायथन में एक पैरामीटर के रूप में एक विधि कैसे पारित कर सकता हूं


190

क्या किसी विधि को एक विधि के रूप में पारित करना संभव है?

self.method2(self.method1)

def method1(self):
    return 'hello world'

def method2(self, methodToRun):
    result = methodToRun.call()
    return result

जवाबों:


263

हां यह है, बस विधि के नाम का उपयोग करें, जैसा आपने लिखा है। पाइथन में विधियाँ / कार्य किसी अन्य चीज़ की तरह ही होते हैं, और आप उन्हें वैसा ही कर सकते हैं, जिस तरह से आप चर करते हैं। वास्तव में, आप एक चर (या फ़ंक्शन) के बारे में एक चर के रूप में सोच सकते हैं जिसका मूल्य वास्तविक कॉल करने योग्य कोड ऑब्जेक्ट है।

FYI करें, कोई callविधि नहीं है - मुझे लगता है कि इसे कहा जाता है __call__, लेकिन आपको इसे स्पष्ट रूप से लागू करने की आवश्यकता नहीं है:

def method1():
    return 'hello world'

def method2(methodToRun):
    result = methodToRun()
    return result

method2(method1)

यदि आप method1तर्कों के साथ बुलाया जाना चाहते थे , तो चीजें थोड़ी अधिक जटिल हो जाती हैं। method2तर्कों को पारित करने के तरीके के बारे में थोड़ी जानकारी के साथ लिखा जाना चाहिए method1, और इसे कहीं से उन तर्कों के लिए मान प्राप्त करने की आवश्यकता है। उदाहरण के लिए, यदि method1एक तर्क लेना चाहिए:

def method1(spam):
    return 'hello ' + str(spam)

फिर आप method2इसे एक तर्क के साथ लिखने के लिए कह सकते हैं जो इसमें पास हो जाता है:

def method2(methodToRun, spam_value):
    return methodToRun(spam_value)

या एक तर्क के साथ कि यह खुद की गणना करता है:

def method2(methodToRun):
    spam_value = compute_some_value()
    return methodToRun(spam_value)

आप इसमें दिए गए मानों और गणना किए गए मानों के अन्य संयोजनों का विस्तार कर सकते हैं, जैसे

def method1(spam, ham):
    return 'hello ' + str(spam) + ' and ' + str(ham)

def method2(methodToRun, ham_value):
    spam_value = compute_some_value()
    return methodToRun(spam_value, ham_value)

या यहां तक ​​कि खोजशब्द तर्क के साथ

def method2(methodToRun, ham_value):
    spam_value = compute_some_value()
    return methodToRun(spam_value, ham=ham_value)

यदि आप नहीं जानते, लिखते समय method2, क्या तर्क methodToRunलेने जा रहे हैं, तो आप इसे सामान्य तरीके से कॉल करने के लिए तर्क अनपैकिंग का भी उपयोग कर सकते हैं:

def method1(spam, ham):
    return 'hello ' + str(spam) + ' and ' + str(ham)

def method2(methodToRun, positional_arguments, keyword_arguments):
    return methodToRun(*positional_arguments, **keyword_arguments)

method2(method1, ['spam'], {'ham': 'ham'})

इस मामले में positional_argumentsएक सूची या तुच्छ या समान होने की आवश्यकता है, और keyword_argumentsएक तानाशाही या समान है। में method2आप संशोधित कर सकते हैं positional_argumentsऔर keyword_arguments(जैसे जोड़ सकते हैं या कुछ तर्क हटाने या मूल्यों को बदलने के लिए) इससे पहले कि आप कहते हैं method1


34

हाँ यह संभव है। बस इसे कॉल करें:

class Foo(object):
    def method1(self):
        pass
    def method2(self, method):
        return method()

foo = Foo()
foo.method2(foo.method1)

1
क्या होगा अगर कोई उदाहरण नहीं है foo?
लेई यांग

1
फिर आपको बस फू की जरूरत नहीं है, जैसे: def method1(): pass def method2(method) return method() method2(method1)
टॉम

14

यहां एक स्टैंड-अलोन वर्किंग उदाहरण दिखाने के लिए आपका उदाहरण फिर से लिखा गया है:

class Test:
    def method1(self):
        return 'hello world'

    def method2(self, methodToRun):
        result = methodToRun()
        return result

    def method3(self):
        return self.method2(self.method1)

test = Test()

print test.method3()

6

हाँ; कार्य (और विधियाँ) पायथन में प्रथम श्रेणी की वस्तुएँ हैं। निम्नलिखित कार्य:

def foo(f):
    print "Running parameter f()."
    f()

def bar():
    print "In bar()."

foo(bar)

आउटपुट:

Running parameter f().
In bar().

इस प्रकार के प्रश्न पायथन इंटरप्रेटर का उपयोग करके उत्तर देने के लिए तुच्छ हैं, या अधिक सुविधाओं के लिए, आईपीथॉन शेल।


5

यदि आप तर्क के रूप में एक वर्ग की एक विधि पारित करना चाहते हैं, लेकिन अभी तक वह वस्तु नहीं है, जिस पर आप उसे कॉल करने जा रहे हैं, तो आप पहले तर्क के रूप में एक बार वस्तु को पास कर सकते हैं (अर्थात "स्व" बहस)।

class FooBar:

    def __init__(self, prefix):
        self.prefix = prefix

    def foo(self, name):
        print "%s %s" % (self.prefix, name)


def bar(some_method):
    foobar = FooBar("Hello")
    some_method(foobar, "World")

bar(FooBar.foo)

यह "हैलो वर्ल्ड" प्रिंट करेगा


4

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

def method1():
    return 'hello world'

def method2(methodToRun):
    result = methodToRun()
    return result

method2(method1)

लेकिन कहते हैं कि आपके पास एक (या अधिक) तर्क हैं method1:

def method1(param):
    return 'hello ' + str(param)

def method2(methodToRun):
    result = methodToRun()
    return result

तो आप बस के method2रूप में आह्वान कर सकते हैं method2(lambda: method1('world'))

method2(lambda: method1('world'))
>>> hello world
method2(lambda: method1('reader'))
>>> hello reader

मुझे यहां वर्णित अन्य उत्तरों की तुलना में यह बहुत साफ लगता है।


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

3

विधियां किसी भी अन्य की तरह वस्तुएं हैं। तो आप उन्हें चारों ओर से गुजार सकते हैं, उन्हें सूचियों और डायकों में संग्रहीत कर सकते हैं, जो कुछ भी आप उनके साथ पसंद करते हैं। उनके बारे में विशेष बात यह है कि वे कॉल करने योग्य वस्तु हैं ताकि आप उन __call__पर आक्रमण कर सकें। __call__जब आप तर्क के साथ या बिना विधि को लागू करते हैं तो आपको स्वचालित रूप से कॉल किया जाता है, इसलिए आपको केवल लिखने की आवश्यकता है methodToRun()


0

आप जैसा चाहते हैं वैसा नहीं, लेकिन एक संबंधित उपयोगी उपकरण है getattr(), विधि के नाम को एक पैरामीटर के रूप में उपयोग करने के लिए।

class MyClass:
   def __init__(self):
      pass
   def MyMethod(self):
      print("Method ran")

# Create an object
object = MyClass()
# Get all the methods of a class
method_list = [func for func in dir(MyClass) if callable(getattr(MyClass, func))]
# You can use any of the methods in method_list
# "MyMethod" is the one we want to use right now

# This is the same as running "object.MyMethod()"
getattr(object,'MyMethod')()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.