假设我有一个名为 generator
的函数,它返回一个 4 元组,其中随机选择的值在某些预先指定的范围内。假设元组的形式为 (age, sex, location, marital_status)
:
age is in range(5, 85)
sex is a member of the set {"m", "f"}
location is a member of the set of all the cities in California
marital_status is a member of {"married", "single", "separated"}
另一方面,假设我定义了 20 个不同的函数,定义如下:
def p1 (age, sex, location, marital_status)
def p2 (age, sex, location, marital_status)
.
.
其中 p1
应该接收具有以下形式值的参数:
`age` must be in the range 20 to 45
`sex` must be male
`location` could be any city in Southern California
`marital_status` could be either single or married
并想象从 p2
一直到 p20
的一组不同值。
确定哪一组生成值与哪个函数匹配的实用方法是什么?
在这种情况下,所有定义都完全相同,但我可以想象定义中可能存在细微差异的情况,例如 p18
可能是 def p1 (age, location )
对 age
和 location
的可能性范围有具体限制。
附言这些模式不一定相互排斥,这意味着一组生成的值也可能匹配多个函数。
最佳答案
作为 Python 3.X(但不是 2.X)中的 Pythonic 方式,您可以附加 annotation information (关于函数参数和结果的任意用户定义数据)到函数对象。在这里,您可以在装饰器中使用此功能来包装您的函数以检查参数的范围。
例如,您可以使用以下范围测试函数:
def rangetest(func):
def onCall(**kargs):
argchecks = func.__annotations__
if all(val in range(*argchecks.get(arg)) for arg,val in kargs.items()):
return func(**kargs)
else :
print ("invalid arg range")
return onCall
@rangetest
def func(a:(1, 5), b:(4,7), c:(0, 10)):
print(a + b + c)
演示:
func(a=2, b=6, c=8)
16
func(a=2, b=6, c=15)
invalid arg range
这里有一点。首先是,由于注释信息在字典中(python 将其作为字典返回)并且字典没有特定的顺序,因此您需要在函数中使用关键字参数才能在注释中获取其相对范围信息字典。
此外,我在这里只使用了数字范围,但您可以使用一些自定义范围,例如您在问题中显示的单词列表。但是在 all
中,您需要检查其类型,然后根据其键入使用正确的操作:
all(kwargs.get(arg) in range(*arg_range) if is instance (arg_range,tuple) else kwargs.get(arg) in arg_range for arg,arg_range in argchecks.items())
关于python - Python中函数参数的模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31579135/