以下是我想做的一个例子。
def f(a, b, c):
if a == 'method1':
c = 0
return b + c
在此功能中,如果满足条件c
,则不需要参数a='method1'
。
不过,我仍然可以使用f(a='method1', b=1, c=2)
调用该函数,其作用与f(a='method1', b=1, c=0)
相同。
对此的一种解决方案是将参数c
默认设置为0
def f(a, b, c=0):
if a == 'method1':
c = 0
return b + c
现在我可以打电话给f(a='method1',b=1)
,这正是我想要的。问题是,我仍然可以在调用c
中更改参数f(a='method1',b=1,c=1)
,但我不希望用户这样做。
我可以在函数签名中而不在正文中强制执行此条件吗(即,我不想在正文中使用if
)。或者,如果还有更好的解决方案,请告知。
类似
def f(a, b, c = 0 if a == 'method1', else c is required):
return b + c
谢谢。
答案 0 :(得分:1)
嗯...这似乎似乎可以用functools.singledispatch
和typing.Literal
来完成,但是我不能让它们至少在python 3.7中一起工作(使用Literal
来自typing_extensions
模块)。我认为一般来说,singledispatch
可能是唯一可以真正满足您要求的工具,因为不同的注册函数可以具有完全不同的签名。但是,为此,我们的方法需要为不同的类。
from functools import singledispatch
class Method1():
pass
class OtherMethods():
pass
@singledispatch
def f(method, b, c):
return b + c
@f.register(Method1)
def _(method, b):
return b
f(Method1(), 12) # returns 12
f(Method1(), 12, 7) # raises an error
f(OtherMethods(), 12) # raises an error
f(OtherMethods(), 12, 7) # returns 19
现在,这并不是您真正要求的,而是在签名中强制使用了参数。
如果某个人更了解singledispatch
和Literal
的实现,也许他们可以解释两者之间的相互作用。
一件更容易做的事情就是简单地将c
定义为默认值为某个无效值。
def f(a, b, c=None):
if a == 'method1':
c = 0
return b + c
这解决了以下问题:如果用户忘记为c
以外的方法设置method1
,他们将收到一条(可能是错误的)错误消息。但是,这并不能解决以下事实:如果在使用c
时设置method1
,则该值将被静默忽略,并可能引起混乱。
答案 1 :(得分:1)
a
,b
和c
都是在运行时动态分配的。您无法在签名中弥补这一点。需要在运行时进行检测,您也可以像其他任何地方一样在if
中进行检测。不过,您可以专门研究函数名称级别,而python将负责检测参数数量。
def f(b,c):
return b + c
def f_method1(b):
return f(b, 0)
def f_method2(half_a_c):
return f(0, half_a_c*2)