最Pythonic的方式提供两种不同的实例化方式?

问题描述 投票:0回答:1

假设我有一个类

AmbiguousClass
,它有两个属性,
a
b
(假设它们都是
int
,但它可以更通用)。它们通过一些可逆方程相关,这样我就可以从 b 计算 a 并计算出 a 的倒数。

我想让用户可以通过提供

 AmbiguousClass
a
来实例化
b
,具体取决于对他们来说更容易的方式。请注意,实例化变量的两种方法可以具有相同的签名,因此这不是典型的多态性示例。不提供或两者都提供应该会导致错误/警告。

__init__
函数中执行此操作的最 Pythonic 方法或最佳实践是什么?

我最好的猜测是类似的东西,但对我来说它感觉不太Pythonic:

class AmbiguousClass():
    def __init__(self, a=None, b=None):
        #if no parameter is provided, we raise an error (can not instantiate)
        if a is None and b is None:
            raise SomeCustomError()

        #if both a and b are provided, this seems redundant, a warning is raised
        elif a is not None and b is not None:
            warnings.warn(f"are you sure that you need to specify both a and b?")
            self.a = a 
            self.b = b

        # if a is provided, we calculate b from it
        elif a is not None:
            self.a = a
            self.b = calculateB(self.a)

        # if b is provided:
        elif b is not None:
            self.b =b
            self.a = calculateA(self.b)

然后,用户必须通过指定他提供的关键字来实例化该类:

var1, var2 = AmbiguousClass(a=3), AmbiguousClass(b=6)

这感觉有点笨拙,特别是如果用户决定提供参数而不提供关键字(默认情况下为

a
,但从用户角度来看并不清楚,可能会导致意外行为)

python overloading instantiation
1个回答
0
投票

您当前的实现实际上非常Pythonic,并且使用带有默认值的关键字参数是Python 中处理可选参数的常见方法。然而,总是有改进的空间。这是使用类方法的另一种方法:

class AmbiguousClass:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    @classmethod
    def from_a(cls, a):
        return cls(a, calculateB(a))

    @classmethod
    def from_b(cls, b):
        return cls(calculateA(b), b)

    @staticmethod
    def calculateA(b):
        # Your formula for calculating a from b here
        pass

    @staticmethod
    def calculateB(a):
        # Your formula for calculating b from a here
        pass

通过此实现,用户将使用两个类方法之一实例化该类: 蟒蛇

var1 = AmbiguousClass.from_a(3)
var2 = AmbiguousClass.from_b(6)

通过使用具有描述性名称的类方法,用户可以更明确地了解它们提供的值。它还可以防止用户同时使用 a 和 b 或两者都不使用 a 和 b 实例化类的潜在情况,这会导致原始实现中出现错误。

© www.soinside.com 2019 - 2024. All rights reserved.