تمرير الوظائف مع الوسائط إلى وظيفة أخرى في بايثون؟

StackOverflow https://stackoverflow.com/questions/803616

  •  03-07-2019
  •  | 
  •  

سؤال

هل من الممكن تمرير الوظائف مع الوسائط إلى وظيفة أخرى في بايثون؟

قل لشيء مثل:

def perform(function):
    return function()

لكن الوظائف التي سيتم تمريرها سيكون لها وسيطات مثل:

action1()
action2(p)
action3(p,r)
هل كانت مفيدة؟

المحلول

هل يعني هذا؟

def perform( fun, *args ):
    fun( *args )

def action1( args ):
    something

def action2( args ):
    something

perform( action1 )
perform( action2, p )
perform( action3, p, r )

نصائح أخرى

وهذا هو ما امدا ل:

def Perform(f):
    f()

Perform(lambda: Action1())
Perform(lambda: Action2(p))
Perform(lambda: Action3(p, r))

ويمكنك استخدام وظيفة جزئية من functools مثل ذلك.

from functools import partial

def perform(f):
    f()

perform(Action1)
perform(partial(Action2, p))
perform(partial(Action3, p, r))

ويعمل أيضا مع الكلمات الرئيسية

perform(partial(Action4, param1=p))

استخدم functools.partial، وليس lambdas! وأوقيانوسيا نفذ هو وظيفة غير مجدية، يمكنك تمرير حول وظائف مباشرة.

for func in [Action1, partial(Action2, p), partial(Action3, p, r)]:
  func()

و(أشهر في وقت لاحق) مثال حقيقي صغير حيث امدا مفيد، الجزئي لا:
تقول انك تريد مختلف 1 الأبعاد المقاطع العرضية من خلال وظيفة 2-الأبعاد، مثل شرائح من خلال صف من التلال.
quadf( x, f ) يأخذ 1-د f وتصفه لمختلف x.
أن نسميها لخفض العمودية في ص = -1 0 1 وتخفيضات الأفقية عند 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 )

وبقدر ما أعرف، partial لا تستطيع أن تفعل هذا -

quadf( y, partial( f, x=1 ))
TypeError: f() got multiple values for keyword argument 'x'

و(كيفية إضافة علامات نمباي، جزئي، لامدا في هذا؟)

وهذا ما يسمى الوظائف الجزئية وهناك على الأقل 3 طرق للقيام بذلك.الطريقة المفضلة لدي هي استخدام lambda لأنها تتجنب الاعتماد على الحزمة الإضافية وهي الأقل تفصيلاً.افترض أن لديك وظيفة add(x, y) وتريد المرور add(3, y) إلى وظيفة أخرى كمعلمة بحيث تحدد الوظيفة الأخرى القيمة الخاصة بها y.

استخدم لامدا

# 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

قم بإنشاء الغلاف الخاص بك

هنا تحتاج إلى إنشاء دالة تُرجع الوظيفة الجزئية.من الواضح أن هذا أكثر إسهابًا.

# 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

استخدم جزئيًا من functools

وهذا مطابق تقريبا ل lambda هو مبين أعلاه.ثم لماذا نحتاج هذا؟هناك أسباب قليلة.باختصار، partial قد يكون أسرع قليلاً في بعض الحالات (انظر ملف تطبيق) وأنه يمكنك استخدامه للربط المبكر مقابل الربط المتأخر لـ 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

وهنا هو وسيلة لتحقيق ذلك مع إغلاق:

    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)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top