将关键字参数和** kwargs传递给子函数

时间:2018-06-16 09:48:21

标签: python python-2.7 function kwargs keyword-argument

我有一个用于执行sql-scripts的子类。

def execute_script(self, script_path, **kwargs):
    pass # connect to db
    query = open(script_path, "r").read().format(**kwargs)
    pass # execute script and close connection

根据我想要执行的操作类型,我使用不同的关键字参数进行不同的包装函数,例如

def create_job(self, **kwargs):
    self.execute_script("create_job.sql", **kwargs)

现在,这非常适合格式化我的sql脚本以包含我的关键字参数,例如,我执行create_job(job_name='foo')。该脚本获取job_name并使用.format() - 方法将其放入我的sql脚本中,如上所示。

但是,随着sql脚本变得越来越长,并且需要传入更多参数,我可能会更难记住需要传递哪些参数,因此我想从*kwargs切换到显式关键字参数,如下所示:

def create_job2(self, job_name, **kwargs):
    self.execute_script("create_job.sql", **kwargs)

但是,这会给我带来以下错误:

KeyError: 'job_name'

所以,我在子函数中包含job_name,认为**kwargs中的execute_script()参数意味着我可以将任意数量的关键字参数传递给函数。 然而,

def create_job3(self, job_name, **kwargs):
    self.execute_script("create_job.sql", job_name, **kwargs)

结果

TypeError: execute_script() takes exactly 2 arguments (3 given)

如果我省略了子函数execute_script()的**kwargs参数,则会发生同样的错误

我的问题:我如何修改execute_script()函数,以便将任何关键字参数传递给包装函数?

或者(这实际上是首选),我可以留下**kwargs - 内涵,而是使用文档字符串或任何其他机制来提醒我需要传递的参数(我指的是一个弹出框并突出显示所需的参数,如Sublime Text或PyCharm正在做的事情)?

1 个答案:

答案 0 :(得分:0)

使用此代码:

def create_job2(self, job_name, **kwargs):
    self.execute_script("create_job.sql", **kwargs)

def execute_script(self, script_path, **kwargs):
    pass # connect to db
    query = open(script_path, "r").read().format(**kwargs)
    pass # execute script and close connection

job_name论证正在失去""在create_job内,而不是传递给execute_scriptkwargs只是您可以编辑的映射:

def create_job2(self, job_name, **kwargs):
    kwargs['job_name'] = job_name
    self.execute_script("create_job.sql", **kwargs)

但是,由于您实际上并未在job_name内使用create_job,因此我不认为以这种方式将其分解是有帮助的(并且会坚持您原来的create_job定义{1}})。

KeyError表示某些内容正在等待命名参数job_name,或者您试图将其从kwargs dict中拉出来。

正如您所指出的,记住"记住" (或被提醒)参数是在方法定义中明确列出它们。

但另一个是创建一个新类,例如:

class Job:
    def __init__(self, name, foo, bar, ...):
        self.name = name
        ...

所以你在一个地方有一堆争论可能很烦人且很难维护,但它只在一个地方而且在你的每个职能中都没有重复。

然后在函数/方法之间传递Job对象,并访问Job实例属性。

根据您的结构,您甚至可以实现Job.execute()方法。