将 partial 与条件默认参数一起使用
Using partial with a conditional default argument
我在库函数上使用 partial
为其提供其中一个参数的默认值
library_func = lambda x, y, z : x + y + z
my_func = functools.partial(library_func, z = 5) #default value for one of the variables
# equiv to lambda x, y : x + y + 5
现在假设我希望 z 取决于 y 的值,而不是常量默认 z。例如,我们在字典中查找 z,其中的键是不同的 y 值。
z = {"1":7,"2":8}[str(y)]
# now my_func(x,y) = library_func(x,y,z = f(y))
这可能吗?在我的用例中,我有一个 class 保持与数据库的连接 (self.engine
)
self.engine = sqlalchemy.create_engine(connection_string)
self.read_sql = partial(pd.read_sql, con = self.engine)
和 pd.read_sql
的签名类似于 pd.read_sql(con , name, columns ...)
我想根据传递的名称的值为列设置默认值。
我想过
self.read_sql = partial(pd.read_sql, con = self.engine, columns = lambda name: self.name_to_column_dict[name])
但出现错误(有充分理由!)
您可以改用包装函数:
def my_func(x, y):
return library_func(x, y, {"1":7,"2":8}[str(y)])
或者,如果您不想按照评论中的建议重新键入所有关键字参数,则可以使用 inspect.signature
获取包装函数的签名,然后将传入的参数绑定到参数,以便您可以使用字典键访问它们,无论参数是作为位置参数还是作为关键字参数传入:
import inspect
def my_func(*args, **kwargs):
bound = sig.bind(*args, **kwargs)
bound.apply_defaults()
return library_func(**bound.arguments, z={"1":7,"2":8}[str(bound.arguments['y'])])
sig = inspect.signature(my_func)
不,partial
函数的默认值在调用函数之前计算。
理想情况下,可以修改库函数:
def library_func(x, y, z=None):
if z is None:
z = {'1': 7, '2': 8}[y]
return x + y + z
但如果这不可能,您可以使用包装函数:
def library_func(x, y, z):
return x + y + z
def library_func_wrapper(*args):
return library_func(*args, {'1': 7, '2': 8}[str(args[-1])])
res = library_func_wrapper(6, 2) # 16
我在库函数上使用 partial
为其提供其中一个参数的默认值
library_func = lambda x, y, z : x + y + z
my_func = functools.partial(library_func, z = 5) #default value for one of the variables
# equiv to lambda x, y : x + y + 5
现在假设我希望 z 取决于 y 的值,而不是常量默认 z。例如,我们在字典中查找 z,其中的键是不同的 y 值。
z = {"1":7,"2":8}[str(y)]
# now my_func(x,y) = library_func(x,y,z = f(y))
这可能吗?在我的用例中,我有一个 class 保持与数据库的连接 (self.engine
)
self.engine = sqlalchemy.create_engine(connection_string)
self.read_sql = partial(pd.read_sql, con = self.engine)
和 pd.read_sql
的签名类似于 pd.read_sql(con , name, columns ...)
我想根据传递的名称的值为列设置默认值。
我想过
self.read_sql = partial(pd.read_sql, con = self.engine, columns = lambda name: self.name_to_column_dict[name])
但出现错误(有充分理由!)
您可以改用包装函数:
def my_func(x, y):
return library_func(x, y, {"1":7,"2":8}[str(y)])
或者,如果您不想按照评论中的建议重新键入所有关键字参数,则可以使用 inspect.signature
获取包装函数的签名,然后将传入的参数绑定到参数,以便您可以使用字典键访问它们,无论参数是作为位置参数还是作为关键字参数传入:
import inspect
def my_func(*args, **kwargs):
bound = sig.bind(*args, **kwargs)
bound.apply_defaults()
return library_func(**bound.arguments, z={"1":7,"2":8}[str(bound.arguments['y'])])
sig = inspect.signature(my_func)
不,partial
函数的默认值在调用函数之前计算。
理想情况下,可以修改库函数:
def library_func(x, y, z=None):
if z is None:
z = {'1': 7, '2': 8}[y]
return x + y + z
但如果这不可能,您可以使用包装函数:
def library_func(x, y, z):
return x + y + z
def library_func_wrapper(*args):
return library_func(*args, {'1': 7, '2': 8}[str(args[-1])])
res = library_func_wrapper(6, 2) # 16