我想知道实现可以在不同模式下运行的函数的最pythonic方法,即根据调用的模式执行稍微不同的任务。
例如,我有以下内容根据一组输入索引提取numpy数组的子集。通常我会希望将这些索引作为[xMin, xMax, yMin, yMax]
形式的列表或元组传递,但我有时可能想要提供中心点和宽度/高度,如([xCoord, yCoord], [width, height])
。 (请注意,这是空间数据& xMin
,yMin
等等。请参阅数组边界的空间坐标。)
def get_subset(array, *args):
## If window extents are given
if len(args) == 1:
[(xMin,xMax,yMin,yMax)] = args
## Set NULL extents to array bounds
if xMin is None: xMin = array.xMin
if xMax is None: xMax = array.xMax
if yMin is None: yMin = array.yMin
if yMax is None: yMax = array.yMax
## Convert window extents to array indices
winLx = int(xMin - array.xMin)
winRx = int(xMax - array.xMin)
winBy = int(array.yMax - yMin)
winTy = int(array.yMax - yMax)
## If window centroid and dimensions are given
elif len(args) == 2:
[(easting,northing),(width,height)] = args
# Convert input coordinates into array indices
xCell = int(easting - array.xMin)
yCell = int(array.yMax - northing)
# Generate L(eft), R(ight), T(op) and B(ottom) window extents
winLx = xCell - width//2
winRx = xCell + width//2
winBy = yCell + height//2
winTy = yCell - height//2
subset = array.data[winTy:winBy, winLx:winRx, :]
有没有更好,更简洁或更pythonic的方式来做到这一点?在过去,我尝试在我的函数中使用mode
参数,然后使用if
循环来获取我想要的功能(类似get_subset(array, window, mode='extent')
),这最终与我上面所示的内容。但是我想知道是否有一种很好的方法可以使用装饰器或其他一些python功能来实现这一目标。
答案 0 :(得分:3)
选项A) 您将该功能分为两个功能。
get_subset_using_extents(array, extents)
get_subset_using_centroid_and_dimension(array, centroid, dimension)
优点:
选项B) 你提出的选择。
def get_subset(array, *args):
if len(args) == 1:
return getsubset_using_extents(array, args[0])
#Or just lay out all of the code here like you had done
elif len(args) == 2:
return get_subset_using_centroid_and_dimension(array, arg[0], arg[1])
#Or just lay out all of the code here like you had done
else:
raise TypeError("get_subset() takes either 2 or 3 arguments")
优点:
缺点:
选项C) 特定于模式的项目存储在字典中。
def get_subset(array, mode, options):
if mode == "extent":
return getsubset_using_extents(array, options["extent"])
elif mode == "centroid_dimensions":
return get_subset_using_centroid_and_dimension(array, options["centroid"],
options["dimensions"])
else:
raise SubsetException("Invalid Mode: " + mode)
优势
函数名称很容易记住,并且因为调用者需要声明所使用的模式,所以仍然可以明白如何获得子集。
允许您在不更改功能签名的情况下轻松添加/更改/删除选项。
强制用户在使用您的功能时明确命名选项键。在您的情况下,这并不重要,但此技术可用于防止看起来像some_function(true, true, false, true)
的函数调用。 (编辑:刚发现你也可以this。)
<强>思想强>
选项A
因为有两种不同的模式没有任何重叠选项,所以这是我可以选择的选项。
选项B
我绝不会使用此选项。 Psuedo重载这样的函数只不是Pythonic的事情。
选项C
在你的情况下,这不是必需的,但是如果这两种模式有很多选项,其中一些在不同模式之间共享,那么这将是一个很好的模式。