Python API 设计中的重载(或替代方案)

2023-11-22

我有一个大型的现有程序库,当前具有 .NET 绑定,并且我正在考虑编写 Python 绑定。现有的 API 广泛使用基于签名的重载。所以,我有大量静态函数,例如:

Circle(p1, p2, p3) -- Creates a circle through three points
Circle(p, r)       -- Creates a circle with given center point and radius
Circle(c1, c2, c3) -- Creates a circle tangent to three curves

在某些情况下,必须以不同的方式使用相同的输入,因此基于签名的重载不起作用,我必须使用不同的函数名称。例如

BezierCurve(p1,p2,p3,p4) -- Bezier curve using given points as control points
BezierCurveThroughPoints(p1,p2,p3,p4) -- Bezier curve passing through given points

我认为第二种技术(使用不同的函数名称)可以在 Python API 中的任何地方使用。所以,我本来

CircleThroughThreePoints(p1, p2, p3)
CircleCenterRadius(p, r)
CircleTangentThreeCurves(c1, c2, c3)

但这些名称看起来冗长得令人不快(我不喜欢缩写),并且发明所有这些名称将是一个相当大的挑战,因为该库有数千个函数。

低优先级:
努力(就我而言)——我不在乎是否需要编写大量代码。
表现

高优先级:
易于调用者使用/理解(许多人是编程新手)。
我很容易写出好的文档。
简单性——避免调用者代码中需要高级概念。

我确信我不是第一个希望在 Python 中实现基于签名的重载的人。人们通常使用哪些解决方法?


一种选择是在构造函数中专门使用关键字参数,并包含逻辑来确定应该使用什么:

class Circle(object):
    def __init__(self, points=(), radius=None, curves=()):
        if radius and len(points) == 1:
            center_point = points[0]
            # Create from radius/center point
        elif curves and len(curves) == 3:
            # create from curves
        elif points and len(points) == 3:
            # create from points
        else:
            raise ValueError("Must provide a tuple of three points, a point and a radius, or a tuple of three curves)

您还可以使用类方法来使 API 用户更轻松:

class Circle(object):
    def __init__(self, points=(), radius=None, curves=()):
         # same as above

    @classmethod
    def from_points(p1, p2, p3):
        return cls(points=(p1, p2, p3))

    @classmethod
    def from_point_and_radius(cls, point, radius):
        return cls(points=(point,), radius=radius)

    @classmethod
    def from_curves(cls, c1, c2, c3):
        return cls(curves=(c1, c2, c3))

Usage:

c = Circle.from_points(p1, p2, p3)
c = Circle.from_point_and_radius(p1, r)
c = Circle.from_curves(c1, c2, c3)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python API 设计中的重载(或替代方案) 的相关文章

随机推荐