Kaydet (Commit) 74d09144 authored tarafından Mark Dickinson's avatar Mark Dickinson

Turn classmethods into staticmethods, and avoid calling the constructor

of subclasses of Rational.  (See discussion in issue #1682.)
üst ac094dc8
...@@ -106,48 +106,48 @@ class Rational(RationalAbc): ...@@ -106,48 +106,48 @@ class Rational(RationalAbc):
self._denominator = int(denominator // g) self._denominator = int(denominator // g)
return self return self
@classmethod @staticmethod
def from_float(cls, f): def from_float(f):
"""Converts a finite float to a rational number, exactly. """Converts a finite float to a rational number, exactly.
Beware that Rational.from_float(0.3) != Rational(3, 10). Beware that Rational.from_float(0.3) != Rational(3, 10).
""" """
if not isinstance(f, float): if not isinstance(f, float):
raise TypeError("%s.from_float() only takes floats, not %r (%s)" % raise TypeError("Rational.from_float() only takes floats, "
(cls.__name__, f, type(f).__name__)) "not %r (%s)" % (f, type(f).__name__))
if math.isnan(f) or math.isinf(f): if math.isnan(f) or math.isinf(f):
raise TypeError("Cannot convert %r to %s." % (f, cls.__name__)) raise TypeError("Cannot convert %r to Rational." % f)
return cls(*f.as_integer_ratio()) return Rational(*f.as_integer_ratio())
@classmethod @staticmethod
def from_decimal(cls, dec): def from_decimal(dec):
"""Converts a finite Decimal instance to a rational number, exactly.""" """Converts a finite Decimal instance to a rational number, exactly."""
from decimal import Decimal from decimal import Decimal
if not isinstance(dec, Decimal): if not isinstance(dec, Decimal):
raise TypeError( raise TypeError(
"%s.from_decimal() only takes Decimals, not %r (%s)" % "Rational.from_decimal() only takes Decimals, not %r (%s)" %
(cls.__name__, dec, type(dec).__name__)) (dec, type(dec).__name__))
if not dec.is_finite(): if not dec.is_finite():
# Catches infinities and nans. # Catches infinities and nans.
raise TypeError("Cannot convert %s to %s." % (dec, cls.__name__)) raise TypeError("Cannot convert %s to Rational." % dec)
sign, digits, exp = dec.as_tuple() sign, digits, exp = dec.as_tuple()
digits = int(''.join(map(str, digits))) digits = int(''.join(map(str, digits)))
if sign: if sign:
digits = -digits digits = -digits
if exp >= 0: if exp >= 0:
return cls(digits * 10 ** exp) return Rational(digits * 10 ** exp)
else: else:
return cls(digits, 10 ** -exp) return Rational(digits, 10 ** -exp)
@classmethod @staticmethod
def from_continued_fraction(cls, seq): def from_continued_fraction(seq):
'Build a Rational from a continued fraction expessed as a sequence' 'Build a Rational from a continued fraction expessed as a sequence'
n, d = 1, 0 n, d = 1, 0
for e in reversed(seq): for e in reversed(seq):
n, d = d, n n, d = d, n
n += e * d n += e * d
return cls(n, d) if seq else cls(0) return Rational(n, d) if seq else Rational(0)
def as_continued_fraction(self): def as_continued_fraction(self):
'Return continued fraction expressed as a list' 'Return continued fraction expressed as a list'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment