পাইথনে প্যারামিটার হিসাবে আমি কীভাবে কোনও পদ্ধতি পাস করব


190

প্যারামিটার হিসাবে কোনও পদ্ধতিতে কোনও পদ্ধতি পাস করা কি সম্ভব?

self.method2(self.method1)

def method1(self):
    return 'hello world'

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

উত্তর:


263

হ্যাঁ এটি হ'ল, আপনি যেমন লিখেছেন তেমন পদ্ধতিটির নামটি ব্যবহার করুন। পদ্ধতিগুলি / ক্রিয়াকলাপগুলি পাইথনের বস্তু যা অন্য যে কোনও কিছুর মতো, এবং আপনি এগুলি ভেরিয়েবলগুলি যেভাবে করতে পারেন সেদিকেই তা পাস করতে পারেন। প্রকৃতপক্ষে, আপনি এমন একটি পদ্ধতি (বা ফাংশন) সম্পর্কে ভেরিয়েবল হিসাবে ভাবতে পারেন যার মানটি প্রকৃত কলযোগ্য কোড অবজেক্ট।

এফওয়াইআই, কোনও 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)

আপনি এটিকে পাস করা মানগুলির মতো অন্য সংমিশ্রণগুলিতে প্রসারিত করতে পারেন values

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')()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.