Python __添加以支持不同类型的添加?

Python __添加以支持不同类型的添加?,python,overloading,add,Python,Overloading,Add,如果python是一种支持重载的静态编程语言,那么解决这个问题将非常容易。我正在创建一个名为Complex的类,它是复数的表示形式(我知道python有自己的,但我想自己创建一个),其中a是实数,b是虚数(Complex(a,b))。它应该支持同时添加复杂实例(Complex(2,4)+Complex(4,5)=Complex(6,9)),以及添加整数(Complex(2,3)+4=Complex(6,3))。但是,由于python的特性 \uuuuuuuuuuuuuuuuuuuuuuuuuuu

如果python是一种支持重载的静态编程语言,那么解决这个问题将非常容易。我正在创建一个名为Complex的类,它是复数的表示形式(我知道python有自己的,但我想自己创建一个),其中a是实数,b是虚数(
Complex(a,b)
)。它应该支持同时添加复杂实例(
Complex(2,4)+Complex(4,5)=Complex(6,9)
),以及添加整数(
Complex(2,3)+4=Complex(6,3)
)。但是,由于python的特性

\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

…我必须选择类将支持的类型,因为它在编译时不会识别类型,也不支持函数重载。最好的解决方案是什么?是否必须针对
其他
参数的数据类型编写if语句?

这里有什么问题

您始终可以检查python对象的类型:

if type(other) != type(self):
    # raise some error
# do addition
return 
混合类型操作 Python中的
numbers
模块可用于实现您自己的数字类。除此之外,它还使用了
\uuuuuuuuuuuuuuuuuuuuuuuuuu添加
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

例子 新数字类型的实现 如果您想实现一个与Python内置数字类型一起工作的数字类,您可以通过对抽象基类进行子类化来实现自己的
复杂


这一抽象的基类将这一抽象抽象的基类将强制执行所需方法的实施。这一抽象的基类将强制执行所需的执行执行执行所需的执行所需的执行所需的方法
<代码>><代码>>uuuuuuuuuuuuuuuuuuuuuuuuuuu
\uuuuuuu添加uuuuuuuuuuuuu
/code>/code><编码>/编码><代码>/uuuuuuuuuuuuu<<代码<<代码>/编码<<代码>/代码>/代码><代码>复杂uuuu<<代码><代码<<代码><代码<<代码><代码<<代码<<代码><代码>
\uuuu rtruediv\uuuuu
\uuuu truediv\uuuuu
共轭
imag
real
你能做的就是检查事物是否是实例复杂的,如果不是,就把它转换成一个实例,就像这样:

def __add__(self, other):
    if isinstance(other, Complex):
        # do addition
    else:
        return self + Complex(other, 0)
这当然不会消除类型检查,但它会重用您在
\uuuu init\uuuu
中所做的任何操作(这可能是检查输入是int还是float)


如果目前没有在init中进行类型检查,这可能是一个好主意,并且看起来很合理,除了内置的复杂类型。

使用isinstance检查它是否是相同的类型,如果不是,则它是任何类型的数字:

def\uuuu添加(自身、其他):
#这是同一个班级
如果存在(其他,复杂):
#您应该返回相同的类
#如果有人扩展您的类SomeClass(Complex):您应该返回SomeClass而不是Complex对象
返回self.\uuuu类(self.a+other.a,self.b+other.b)
#假设是任何类型的数字
尝试:
返回self.\uuuu类(int(self.a+other),self.b)
除类型错误外:
#更改错误消息
raise TypeError(“不支持的+:'%s'和'%s'(自身类、其他类)的操作数类型)

不一定有最好的解决方案。但在这种情况下:

def __add__(self, other):
    c = make_complex(other)
    return Complex(self.real + c.real, self.imag + real.imag)
这可能是一种方法(尽管我在这里对您的
复杂类做了很多假设)。如果
其他
已经是
复杂类
,则
make_Complex
函数会返回它。如果不是,它会尽力转换(例如,通过构造一个虚部为零的复数,将一个实数转换成一个复数对)。如果失败,它会引发一些合适的例外

使复杂
也适用于
复杂
的构造函数,以便您可以替换以下部件:

e = Complex(1.718, 0) # e (well, not very exactly)
i = Complex(0, 1) # sqrt(-1)
pi = Complex(3.14, 0) # pi
# you know what to do next
与:

例如,(您可以使用
复杂的
构造函数来完成所有工作,使用
isinstance()
来检查参数类型。)


请注意,由于复数加法是可交换的,您可能希望实现
\uuuuradd\uuuuuuu

这就是
\uuuidd\uuuuuuu
,就地加法。取决于复数是否可以就地修改,您可能需要也可能不需要。是的,我忘记了当returning确保返回同一类而非复杂类的对象如果希望复杂类能够成为子类而不强制子类提供自己的函数,可以使用
self.\uuu class\uuuu
来构造返回值。始终建议使用此技术,这样更安全。感谢您对两者之间差异的说明
\uuuuu add\uuuuu
\uuuu iadd\uuuuu
如果您想支持添加不同类型的对象,我认为最好的选择是使用,尽管这可能有点过分。请尝试一下,看看您更喜欢什么:)
e = Complex(1.718, 0) # e (well, not very exactly)
i = Complex(0, 1) # sqrt(-1)
pi = Complex(3.14, 0) # pi
# you know what to do next
e = Complex(1.718)
pi = make_complex(3.14)