เป็นไปได้ไหมที่จะส่งเมธอดเป็นพารามิเตอร์ไปยังเมธอด?
self.method2(self.method1)
def method1(self):
return 'hello world'
def method2(self, methodToRun):
result = methodToRun.call()
return result
เป็นไปได้ไหมที่จะส่งเมธอดเป็นพารามิเตอร์ไปยังเมธอด?
self.method2(self.method1)
def method1(self):
return 'hello world'
def method2(self, methodToRun):
result = methodToRun.call()
return result
คำตอบ:
ใช่มันเป็นเพียงใช้ชื่อของวิธีการตามที่คุณเขียน วิธีการ / ฟังก์ชั่นเป็นวัตถุใน Python เช่นเดียวกับสิ่งอื่นและคุณสามารถส่งผ่านสิ่งเหล่านี้ในแบบที่คุณทำตัวแปร ในความเป็นจริงคุณสามารถคิดเกี่ยวกับวิธีการ (หรือฟังก์ชั่น) เป็นตัวแปรที่มีค่าเป็นวัตถุรหัส callable จริง
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
จะต้องเป็นรายการหรือ tuple หรือคล้ายกันและkeyword_arguments
เป็น dict หรือคล้ายกัน ในmethod2
คุณสามารถปรับเปลี่ยนpositional_arguments
และkeyword_arguments
(เช่นการเพิ่มหรือลบการขัดแย้งบางอย่างหรือเปลี่ยนค่า) method1
ก่อนที่คุณเรียก
ใช่มันเป็นไปได้ แค่เรียกมันว่า:
class Foo(object):
def method1(self):
pass
def method2(self, method):
return method()
foo = Foo()
foo.method2(foo.method1)
def method1(): pass def method2(method) return method() method2(method1)
นี่คือตัวอย่างของคุณเขียนใหม่เพื่อแสดงตัวอย่างการทำงานแบบสแตนด์อโลน:
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()
ใช่; ฟังก์ชั่น (และวิธีการ) เป็นวัตถุชั้นหนึ่งในงูหลาม ผลงานดังต่อไปนี้:
def foo(f):
print "Running parameter f()."
f()
def bar():
print "In bar()."
foo(bar)
ขาออก:
Running parameter f().
In bar().
คำถามประเภทนี้เล็กน้อยที่จะตอบโดยใช้ Python interpreter หรือสำหรับคุณสมบัติเพิ่มเติมเชลล์IPython
ถ้าคุณต้องการส่งเมธอดของคลาสเป็นอาร์กิวเมนต์ แต่ยังไม่มีวัตถุที่คุณจะเรียกมันคุณสามารถส่งวัตถุได้เมื่อคุณมีมันเป็นอาร์กิวเมนต์แรก (เช่น "ตัวเอง" การโต้เถียง).
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)
จะพิมพ์ "Hello World"
คำตอบที่ดีมากมาย แต่แปลกที่ไม่มีใครพูดถึงการใช้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
ฉันพบว่าสิ่งนี้สะอาดกว่าคำตอบอื่น ๆ ที่กล่าวถึงที่นี่
()
ส่วนท้ายของวัตถุในการโทรกลับของฉัน, duh
วิธีการเป็นวัตถุที่เหมือนกัน ดังนั้นคุณสามารถส่งพวกเขาไปรอบ ๆ เก็บไว้ในรายการและ dicts ทำสิ่งที่คุณชอบกับพวกเขา สิ่งที่พิเศษเกี่ยวกับพวกเขาคือพวกมันเป็นวัตถุที่เรียกได้ดังนั้นคุณจึงสามารถเรียก__call__
มันได้ ได้รับการเรียกโดยอัตโนมัติเมื่อคุณเรียกวิธีการมีหรือไม่มีข้อโต้แย้งเพื่อให้คุณเพียงแค่ต้องเขียน__call__
methodToRun()
ไม่ใช่สิ่งที่คุณต้องการอย่างแน่นอน แต่เครื่องมือที่มีประโยชน์ที่เกี่ยวข้องคือ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')()
foo
?