【问题标题】:How to pass a python function with parameters (a closure) into another function?如何将带有参数(闭包)的python函数传递给另一个函数?
【发布时间】:2021-02-14 23:29:00
【问题描述】:

我是一个 Python 菜鸟,目前正在使用 rabbitMQ。我从 rabbitMQ 接收到一个有效负载并对其进行处理。这是第一个函数

def verify_user_id(ch, method, properties, body):
    print("[*] Received message for NIN verification")
    body = json.loads(body)  # convert JSON string to python object
    parameters = body.get('parameters')
    id_info = {
        'first_name': parameters.get('first_name'),
        'last_name': parameters.get('last_name'),
        'country': parameters.get('country'),
        'id_type': parameters.get('id_type'),
        'id_number': parameters.get('id_number'),
        'entered': parameters.get('entered')
    }
    partner_params = {
        'job_id': parameters.get('job_id'),
        'user_id': parameters.get('user_id'),
        'job_type': parameters.get('job_type')
    }
    return body, id_info, partner_params

现在,我想使用上面的函数向服务器发送请求,如下所示:

def smile_identity_func():
    body, id_info, partner_params = verify_user_id()
    try:
      
         connection = IdApi(str(partner_id), str(api_key), sid_server)
         response = connection.submit_job(partner_params, id_info)
         obj = response.json()
         return jsonify(obj)
        
        ch.basic_ack(delivery_tag=method.delivery_tag)
        print(" [x] Done")
    except ValueError as e:
        # some params are not valid
        return str(e)
    except ServerError as e:
        return str(e)

我知道body, id_info, partner_params = verify_user_id() 是错误的,但我不知道如何正确地将verify_user_id() 及其参数ch, method, properties, body 传递到smile_identity_func()

我希望能够以不必为“ch、method、properties、body”指定值的方式执行此操作。

【问题讨论】:

  • 也许我没有正确理解这个问题,但你为什么不能将它们传递给smile_identity_func() 并在该函数内部将它们用作verify_user_id() 的参数?

标签: python rabbitmq pika


【解决方案1】:

您要求的是 Closure 的经典用例,或者特定于 Python 的 A Python Closure

这是如何工作的:

# Create a closure on the `request` function that hard-codes the passed in
# parameters as the context variables to be used when executing the function
def get_request_function(username, password, email):

    # The standard function to call
    def request():
        print("Username {} | Password {} | Email {}".format(username, password, email))

    # return the closure on 'request'
    return request

# Another function that simply calls the function represented by the
# reference passed to it.
def used_passed_in_function(f):
    f()

# Get an instance of our closure, a call to "request", that bakes in
# the context variables we provide.
f = get_request_function("x3-", "f8dJsn9/sd", "x3-@gmail.com")

# Finally, call our sample function that calls whatever function is passed
# to it, passing in our closure to be the function that is called.
used_passed_in_function(f)

结果:

Username x3- | Password f8dJsn9/sd | Email x3-@gmail.com

这确实为您提供了您想要的,能够将某个函数传递给另一个函数,其参数已经绑定到该函数。

请注意,从used_passed_in_function 的角度来看,闭包和对不带参数的常规函数​​的引用没有区别。然而,两者有着根本的不同。

我想我会先笼统地回答这个问题。这是您提供的代码的特定示例:

def smile_identity_func(verify_func):
    # This call to "verify_func" is a call to "verify_user_id" with a set of
    # parameters hard-coded into the call.
    body, id_info, partner_params = verify_func()
    ...

def create_verify_user_id_closure(ch, method, properties, body):
    def baked_verify_user_id():
        return verify_user_id(ch, method, properties, body)
    return baked_verify_user_id

verify_id = create_verify_user_id_closure("sample-ch", "sample-method", "sample-properties", "sample-body")
smile_identity_func(verify_id)

【讨论】:

  • 对不起。我的回答的第一个版本展示了如何创建一个可以传递给函数的闭包,以及如何调用它,但实际上并没有演示将它传递给另一个函数。我的答案的新版本表明>
猜你喜欢
  • 1970-01-01
  • 2014-01-06
  • 1970-01-01
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
  • 2016-06-29
  • 1970-01-01
相关资源
最近更新 更多