Python3中的Duck类型和元组或整数的接受

Python3中的Duck类型和元组或整数的接受,python,python-3.x,duck-typing,Python,Python 3.x,Duck Typing,我正在使用一个在屏幕上显示tilemap的外部(公共域)库。我试图通过使用lambda的dict语句来避免使用长链的if…then…elif进行输入处理,该语句将在按下键(作为dict的键)和视口的当前x,y位置的情况下适当调整视口 lambda以元组的形式返回修改后的x和y坐标,但是设置视口的函数(我意识到确实应该使用@property来处理视口,但是代码已经存在,重新构造它会非常痛苦)将其参数作为单独的x和y作为整数 我可以通过在函数顶部附近插入以下内容使其接受元组: if isinstan

我正在使用一个在屏幕上显示tilemap的外部(公共域)库。我试图通过使用
lambda
dict
语句来避免使用长链的if…then…elif进行输入处理,该语句将在按下键(作为dict的键)和视口的当前x,y位置的情况下适当调整视口

lambda以元组的形式返回修改后的x和y坐标,但是设置视口的函数(我意识到确实应该使用
@property
来处理视口,但是代码已经存在,重新构造它会非常痛苦)将其参数作为单独的x和y作为整数

我可以通过在函数顶部附近插入以下内容使其接受元组:

if isinstance(fx,tuple):
    fx, fy = fx
但是,如果我们想成为超级Pythonic,去冒犯原始库开发人员,这是不行的——duck类型范例表明,任何可以包含x和y值的对象都是可以接受的


如何实现此功能?

使用
*params
调用viewport函数:

coordinates = lambda_mapping[key](argument)
viewport_set(*coordinates)
这将
坐标
元组作为单独的参数应用于
viewport\u set()
函数

演示:

现在,您不必调整viewport函数来获取元组和单独的参数

另一种选择是将第二个坐标设为关键字参数:

def viewport_set(x, y=None):
    if y is None:
        # assume x is a sequence of two coordinates instead
        x, y = x

实际上,您所建议的更改确实允许任何包含x和y值的对象,只要该包含被表示为“在其上迭代将产生x,然后是y,并且没有更多”。这是一个相当通用的接口。这是一个非常方便的技巧,我必须记住(事实上,我确实记得它,但我认为它只适用于dicts)——但问题更多的是修复库,而不是让程序使用它。不过,(编辑的)方式似乎是最好的方式——如果使用库的人决定要传递一个不起作用的函数,他只会像应该的那样被解释器大喊大叫。
def viewport_set(x, y=None):
    if y is None:
        # assume x is a sequence of two coordinates instead
        x, y = x