我有一个用于执行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正在做的事情)?
答案 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_script
。 kwargs
只是您可以编辑的映射:
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()
方法。