gpt4 book ai didi

python - 如何告诉Python,当存在冲突时,我们总是希望将 Foo 类型的对象解释为 Bar 类型的对象?

转载 作者:行者123 更新时间:2023-11-30 23:05:09 25 4
gpt4 key购买 nike

我是新手,所以请原谅不标准的术语,并让我知道是否应该添加代码以使这个问题更清楚。

假设我们尝试在 Python 中创建一个“Rational”类。 (我知道已经内置了一个,但为了这个问题的目的忽略它。)

我们可以使用__add____mul__ ,例如,教 Python 如何解释 a + b 形式的代码或a * b ,

哪里ab是有理数。

现在,可能会发生这样的情况:在其他地方,有人想要计算 a + b ,其中a是有理数但是b是一个整数。我们可以通过修改 __add__ 来做到这一点Rational 类中的代码包含 if 语句,例如,

def __add__(self, b):
if isinstance(b, int):
brat = rational(b, 1)
return self + brat
else:
y = rational(self.num*b.den + b.num*self.den , b.den*self.den)
y = y.lowest_terms()
return y

我们可以类似地修改我们的 __mul__代码,我们的__div__但这种解决方案至少存在两个问题:

  1. 仅当第二个参数是 int 时才有效。 。首先论证仍然必须是理性的;没有办法写一个Rational 类中的方法允许我们添加 a + b其中 a 是int 且 be 是有理数。
  2. 这是重复的。我们真正想要的是某种技术能够在全局范围内以某种方式说一次,“每当你试图做某事时对多个对象的操作,其中一些是有理数,一些是其中是整数,通过映射 n 将整数视为有理数到 Rational(n, 1)。”

这样的技术存在吗? (我标记了这种强制转换,因为我认为这就是其他上下文中所谓的强制转换,但我的理解是,Python 中不推荐使用强制转换。)

最佳答案

您可以通过在类的初始值设定项中进行映射来避免重复。这是一个处理整数的简单演示。正确处理float将作为读者的练习。 :) 但是,我已经展示了如何轻松实现 __radd____iadd__,这是神奇的方法(又名 dunder 方法)处理+=

我的代码保留了您代码中的 rational 作为类名,尽管 Python 中的类名通常采用 CamelCase。

def gcd(a, b):
while b > 0:
a, b = b, a%b
return a

class rational(object):
def __init__(self, num, den=1):
if isinstance(num, rational):
self.copy(num)
else:
self.num = num
self.den = den

def copy(self, other):
self.num = other.num
self.den = other.den

def __str__(self):
return '{0} / {1}'.format(self.num, self.den)

def lowest_terms(self):
g = gcd(self.num, self.den)
return rational(self.num // g, self.den // g)

def __add__(self, other):
other = rational(other)
y = rational(self.num*other.den + other.num*self.den, other.den*self.den)
return y.lowest_terms()

def __radd__(self, other):
return rational(other) + self

def __iadd__(self, other):
self.copy(self + rational(other))
return self


a = rational(1, 4)
b = rational(2, 5)
c = a + b
print a
print b
print c
print c + 5
print 10 + c
c += 10
print c

输出

1 / 4
2 / 5
13 / 20
113 / 20
213 / 20
213 / 20

您可能希望保留该copy方法供内部使用;通常的约定是在此类名称前面添加一个下划线。

关于python - 如何告诉Python,当存在冲突时,我们总是希望将 Foo 类型的对象解释为 Bar 类型的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33330263/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com