Có thể truyền các hàm có đối số cho hàm khác trong Python không?
Nói cho một cái gì đó như:
def perform(function):
return function()
Nhưng các hàm được truyền sẽ có các đối số như:
action1()
action2(p)
action3(p,r)
Có thể truyền các hàm có đối số cho hàm khác trong Python không?
Nói cho một cái gì đó như:
def perform(function):
return function()
Nhưng các hàm được truyền sẽ có các đối số như:
action1()
action2(p)
action3(p,r)
Câu trả lời:
Bạn có hiểu cái này không?
def perform( fun, *args ):
fun( *args )
def action1( args ):
something
def action2( args ):
something
perform( action1 )
perform( action2, p )
perform( action3, p, r )
perform
và action1
, action2
trên các tập tin khác nhau? @
Đây là những gì lambda dành cho:
def Perform(f):
f()
Perform(lambda: Action1())
Perform(lambda: Action2(p))
Perform(lambda: Action3(p, r))
Bạn có thể sử dụng chức năng một phần từ funcools như vậy.
from functools import partial
def perform(f):
f()
perform(Action1)
perform(partial(Action2, p))
perform(partial(Action3, p, r))
Cũng hoạt động với các từ khóa
perform(partial(Action4, param1=p))
functools.partial
cũng linh hoạt hơn nếu perform
cần bàn giao thêm thông số f
. Ví dụ, người ta có thể gọi perform(partial(Action3, p))
và perform(f)
có thể làm một cái gì đó như f("this is parameter r")
.
Sử dụng funcools.partial, không lambdas! Và ofc Performance là một chức năng vô dụng, bạn có thể chuyển trực tiếp các chức năng.
for func in [Action1, partial(Action2, p), partial(Action3, p, r)]:
func()
(vài tháng sau) một ví dụ thực tế nhỏ trong đó lambda rất hữu ích, một phần là không:
giả sử bạn muốn có các mặt cắt 1 chiều khác nhau thông qua chức năng 2 chiều, giống như các lát cắt qua một dãy đồi.
quadf( x, f )
mất 1-d f
và gọi nó cho nhiều x
.
Để gọi nó là cắt dọc tại y = -1 0 1 và cắt ngang tại x = -1 0 1,
fx1 = quadf( x, lambda x: f( x, 1 ))
fx0 = quadf( x, lambda x: f( x, 0 ))
fx_1 = quadf( x, lambda x: f( x, -1 ))
fxy = parabola( y, fx_1, fx0, fx1 )
f_1y = quadf( y, lambda y: f( -1, y ))
f0y = quadf( y, lambda y: f( 0, y ))
f1y = quadf( y, lambda y: f( 1, y ))
fyx = parabola( x, f_1y, f0y, f1y )
Theo tôi biết, partial
không thể làm điều này -
quadf( y, partial( f, x=1 ))
TypeError: f() got multiple values for keyword argument 'x'
(Làm thế nào để thêm thẻ numpy, một phần, lambda vào đây?)
Đây được gọi là chức năng một phần và có ít nhất 3 cách để làm điều này. Cách ưa thích của tôi là sử dụng lambda vì nó tránh được sự phụ thuộc vào gói bổ sung và ít dài dòng nhất. Giả sử bạn có một hàm add(x, y)
và bạn muốn chuyển add(3, y)
đến một số hàm khác làm tham số sao cho hàm kia quyết định giá trị cho y
.
Sử dụng lambda
# generic function takes op and its argument
def runOp(op, val):
return op(val)
# declare full function
def add(x, y):
return x+y
# run example
def main():
f = lambda y: add(3, y)
result = runOp(f, 1) # is 4
Tạo Wrapper của riêng bạn
Ở đây bạn cần tạo một hàm trả về hàm một phần. Điều này rõ ràng là dài dòng hơn nhiều.
# generic function takes op and its argument
def runOp(op, val):
return op(val)
# declare full function
def add(x, y):
return x+y
# declare partial function
def addPartial(x):
def _wrapper(y):
return add(x, y)
return _wrapper
# run example
def main():
f = addPartial(3)
result = runOp(f, 1) # is 4
Sử dụng một phần từ funcools
Điều này gần như giống hệt như lambda
hiển thị ở trên. Vậy thì tại sao chúng ta cần điều này? Có vài lý do . Nói tóm lại, partial
có thể nhanh hơn một chút trong một số trường hợp (xem phần triển khai của nó ) và bạn có thể sử dụng nó để ràng buộc sớm so với ràng buộc muộn của lambda.
from functools import partial
# generic function takes op and its argument
def runOp(op, val):
return op(val)
# declare full function
def add(x, y):
return x+y
# run example
def main():
f = partial(add, 3)
result = runOp(f, 1) # is 4
Đây là một cách để làm điều đó với một đóng cửa:
def generate_add_mult_func(func):
def function_generator(x):
return reduce(func,range(1,x))
return function_generator
def add(x,y):
return x+y
def mult(x,y):
return x*y
adding=generate_add_mult_func(add)
multiplying=generate_add_mult_func(mult)
print adding(10)
print multiplying(10)
def action1(arg1, arg2=None, arg3=None)
làm thế nào bạn có thể vượt qua một đối số mà bạn dự định được gán cho arg3, ví dụ?