python怎么识别数字,python识别数字

  python怎么识别数字,python识别数字

  概要

  这个提案定义了一个抽象基类(ABC)(PEP 3119)的层次结构,用来表示类像数字(number-like)。它提出了数:复数3360实数3360有理3360整数的层次结构,其中A : B表示“A是B的超类”。这种分层结构的灵感来自Scheme的数字塔。(翻译注:数字-复数-实数-有理数-整数)

  基本原理

  以数字为参数的函数应该能够确定这些数字的属性,并根据数字的类型来决定是否以及何时重载,也就是说函数应该是基于参数的类型来重载的。

  例如,切片要求其参数为积分,而数学模块中的函数要求其参数为实数。

  规范

  该PEP定义了一组抽象基类,并提出了实现一些方法的通用策略。它使用了PEP 3119中的术语,但是这种层次结构对于特定类集的任何系统方法都是有意义的。

  标准库中的类型检查应该使用这些类,而不是特定的内置类型。

  数值类

  先说数类,这是人们想象的数类型的一个模糊概念。该类仅用于重载;它不提供任何操作。

  class(metaclass=ABC meta)3360 pass复数的大部分实现都是可哈希的,但是如果你需要依赖它,就必须明确检查这个层次结构是否支持可变数。

  classComplex(数字):

  “”complexsdefinestheoperationthaworkonthebuildincomplextype。

  简而言之,那些是:conversiontocomplex,bool(),真实,imag,

  ,-,*,/,**,abs(),共轭(),==,和!=.

  如果给定了异构参数,并且没有特殊参数

  关于它们的知识,它应该是完整的

  类型描述如下。

  @抽象方法

  def__complex__(self):

   Returnabuiltincomplexinstance

  def__bool__(self):

  引证(quotation的缩写)

  ;""Trueifself!=0."""

  returnself!=0

  @abstractproperty

  defreal(self):

  """Retrievetherealcomponentofthisnumber.

  ThisshouldsubclassReal.

  """

  raiseNotImplementedError

  @abstractproperty

  defimag(self):

  """Retrievetherealcomponentofthisnumber.

  ThisshouldsubclassReal.

  """

  raiseNotImplementedError

  @abstractmethod

  def__add__(self,other):

  raiseNotImplementedError

  @abstractmethod

  def__radd__(self,other):

  raiseNotImplementedError

  @abstractmethod

  def__neg__(self):

  raiseNotImplementedError

  def__pos__(self):

  """Coercesselftowhateverclassdefinesthemethod."""

  raiseNotImplementedError

  def__sub__(self,other):

  returnself+-other

  def__rsub__(self,other):

  return-self+other

  @abstractmethod

  def__mul__(self,other):

  raiseNotImplementedError

  @abstractmethod

  def__rmul__(self,other):

  raiseNotImplementedError

  @abstractmethod

  def__div__(self,other):

  """a/b;shouldpromotetofloatorcomplexwhennecessary."""

  raiseNotImplementedError

  @abstractmethod

  def__rdiv__(self,other):

  raiseNotImplementedError

  @abstractmethod

  def__pow__(self,exponent):

  """a**b;shouldpromotetofloatorcomplexwhennecessary."""

  raiseNotImplementedError

  @abstractmethod

  def__rpow__(self,base):

  raiseNotImplementedError

  @abstractmethod

  def__abs__(self):

  """ReturnstheRealdistancefrom0."""

  raiseNotImplementedError

  @abstractmethod

  defconjugate(self):

  """(x+y*i).conjugate()returns(x-y*i)."""

  raiseNotImplementedError

  @abstractmethod

  def__eq__(self,other):

  raiseNotImplementedError

  #__ne__isinheritedfromobjectandnegateswhatever__eq__does.Real抽象基类表示在实数轴上的值,并且支持内置的float的操作。实数(Real number)是完全有序的,除了 NaN(本 PEP 基本上不考虑它)。

  

classReal(Complex):

  """ToComplex,Realaddstheoperationsthatworkonrealnumbers.

  Inshort,thoseare:conversiontofloat,trunc(),math.floor(),

  math.ceil(),round(),divmod(),//,%,<,<=,>,and>=.

  Realalsoprovidesdefaultsforsomeofthederivedoperations.

  """

  #XXXWhattodoaboutthe__int__implementationthat's

  #currentlypresentonfloat?Getridofit?

  @abstractmethod

  def__float__(self):

  """AnyRealcanbeconvertedtoanativefloatobject."""

  raiseNotImplementedError

  @abstractmethod

  def__trunc__(self):

  """TruncatesselftoanIntegral.

  ReturnsanIntegralisuchthat:

  *i>=0iffself>0;

  *abs(i)<=abs(self);

  *foranyIntegraljsatisfyingthefirsttwoconditions,

  abs(i)>=abs(j)[i.e.ihas"maximal"absamongthose].

  i.e."truncatetowards0".

  """

  raiseNotImplementedError

  @abstractmethod

  def__floor__(self):

  """FindsthegreatestIntegral<=self."""

  raiseNotImplementedError

  @abstractmethod

  def__ceil__(self):

  """FindstheleastIntegral>=self."""

  raiseNotImplementedError

  @abstractmethod

  def__round__(self,ndigits:Integral=None):

  """Roundsselftondigitsdecimalplaces,defaultingto0.

  IfndigitsisomittedorNone,returnsanIntegral,

  otherwisereturnsaReal,preferablyofthesametypeas

  self.Typesmaychoosewhichdirectiontoroundhalf.For

  example,floatroundshalftowardeven.

  """

  raiseNotImplementedError

  def__divmod__(self,other):

  """Thepair(self//other,self%other).

  Sometimesthiscanbecomputedfasterthanthepairof

  operations.

  """

  return(self//other,self%other)

  def__rdivmod__(self,other):

  """Thepair(self//other,self%other).

  Sometimesthiscanbecomputedfasterthanthepairof

  operations.

  """

  return(other//self,other%self)

  @abstractmethod

  def__floordiv__(self,other):

  """Thefloor()ofself/other.Integral."""

  raiseNotImplementedError

  @abstractmethod

  def__rfloordiv__(self,other):

  """Thefloor()ofother/self."""

  raiseNotImplementedError

  @abstractmethod

  def__mod__(self,other):

  """self%other

  See

  https://mail.python.org/pipermail/python-3000/2006-May/001735.html

  andconsiderusing"self/other-trunc(self/other)"

  insteadifyou'reworriedaboutround-offerrors.

  """

  raiseNotImplementedError

  @abstractmethod

  def__rmod__(self,other):

  """other%self"""

  raiseNotImplementedError

  @abstractmethod

  def__lt__(self,other):

  """<onRealsdefinesatotalordering,exceptperhapsforNaN."""

  raiseNotImplementedError

  @abstractmethod

  def__le__(self,other):

  raiseNotImplementedError

  #__gt__and__ge__areautomaticallydonebyreversingthearguments.

  #(But__le__isnotcomputedastheoppositeof__gt__!)

  #ConcreteimplementationsofComplexabstractmethods.

  #Subclassesmayoverridethese,butdon'thaveto.

  def__complex__(self):

  returncomplex(float(self))

  @property

  defreal(self):

  return+self

  @property

  defimag(self):

  return0

  defconjugate(self):

  """Conjugateisano-opforReals."""

  return+self

我们应该整理 Demo/classes/Rat.py,并把它提升为 Rational.py 加入标准库。然后它将实现有理数(Rational)抽象基类。

  

classRational(Real,Exact):

  """.numeratorand.denominatorshouldbeinlowestterms."""

  @abstractproperty

  defnumerator(self):

  raiseNotImplementedError

  @abstractproperty

  defdenominator(self):

  raiseNotImplementedError

  #ConcreteimplementationofReal'sconversiontofloat.

  #(ThisinvokesInteger.__div__().)

  def__float__(self):

  returnself.numerator/self.denominator

最后是整数类:

  

classIntegral(Rational):

  """Integraladdsaconversiontointandthebit-stringoperations."""

  @abstractmethod

  def__int__(self):

  raiseNotImplementedError

  def__index__(self):

  """__index__()existsbecausefloathas__int__()."""

  returnint(self)

  def__lshift__(self,other):

  returnint(self)<<int(other)

  def__rlshift__(self,other):

  returnint(other)<<int(self)

  def__rshift__(self,other):

  returnint(self)>>int(other)

  def__rrshift__(self,other):

  returnint(other)>>int(self)

  def__and__(self,other):

  returnint(self)&int(other)

  def__rand__(self,other):

  returnint(other)&int(self)

  def__xor__(self,other):

  returnint(self)^int(other)

  def__rxor__(self,other):

  returnint(other)^int(self)

  def__or__(self,other):

  returnint(self)int(other)

  def__ror__(self,other):

  returnint(other)int(self)

  def__invert__(self):

  return~int(self)

  #ConcreteimplementationsofRationalandRealabstractmethods.

  def__float__(self):

  """float(self)==float(int(self))"""

  returnfloat(int(self))

  @property

  defnumerator(self):

  """Integersaretheirownnumerators."""

  return+self

  @property

  defdenominator(self):

  """Integershaveadenominatorof1."""

  return1

运算及__magic__方法的变更

  为了支持从 float 到 int(确切地说,从 Real 到 Integral)的精度收缩,我们提出了以下新的 __magic__ 方法,可以从相应的库函数中调用。所有这些方法都返回 Intergral 而不是 Real。

  __trunc__(self):在新的内置 trunc(x) 里调用,它返回从 0 到 x 之间的最接近 x 的 Integral。

  __floor__(self):在 math.floor(x) 里调用,返回 Integral <= x。

  __ceil__(self):在 math.ceil(x) 里调用,返回最小的 Integral > = x。

  __round__(self):在 round(x) 里调用,返回最接近 x 的 Integral ,根据选定的类型作四舍五入。浮点数将从 3.0 版本起改为向偶数端四舍五入。(译注:round(2.5) 等于 2,round(3.5) 等于 4)。它还有一个带两参数的版本__round__(self, ndigits),被 round(x, ndigits) 调用,但返回的是一个 Real。

  在 2.6 版本中,math.floor、math.ceil 和 round 将继续返回浮点数。

  float 的 int() 转换等效于 trunc()。一般而言,int() 的转换首先会尝试__int__(),如果找不到,再尝试__trunc__()。

  complex.__{divmod, mod, floordiv, int, float}__ 也消失了。提供一个好的错误消息来帮助困惑的搬运工会很好,但更重要的是不出现在 help(complex) 中。

  给类型实现者的说明

  实现者应该注意使相等的数字相等,并将它们散列为相同的值。如果实数有两个不同的扩展,这可能会变得微妙。例如,一个复数类型可以像这样合理地实现 hash():

  

def__hash__(self):

  returnhash(complex(self))

但应注意所有超出了内置复数范围或精度的值。

  添加更多数字抽象基类

  当然,数字还可能有更多的抽象基类,如果排除了添加这些数字的可能性,这会是一个糟糕的等级体系。你可以使用以下方法在 Complex 和 Real 之间添加MyFoo:

  

classMyFoo(Complex):...

  MyFoo.register(Real)

实现算术运算

  我们希望实现算术运算,使得在混合模式的运算时,要么调用者知道如何处理两种参数类型,要么将两者都转换为最接近的内置类型,并以此进行操作。

  对于 Integral 的子类型,这意味着__add__和__radd__应该被定义为:

  

classMyIntegral(Integral):

  def__add__(self,other):

  ifisinstance(other,MyIntegral):

  returndo_my_adding_stuff(self,other)

  elifisinstance(other,OtherTypeIKnowAbout):

  returndo_my_other_adding_stuff(self,other)

  else:

  returnNotImplemented

  def__radd__(self,other):

  ifisinstance(other,MyIntegral):

  returndo_my_adding_stuff(other,self)

  elifisinstance(other,OtherTypeIKnowAbout):

  returndo_my_other_adding_stuff(other,self)

  elifisinstance(other,Integral):

  returnint(other)+int(self)

  elifisinstance(other,Real):

  returnfloat(other)+float(self)

  elifisinstance(other,Complex):

  returncomplex(other)+complex(self)

  else:

  returnNotImplemented

对 Complex 的子类进行混合类型操作有 5 种不同的情况。我把以上所有未包含 MyIntegral 和 OtherTypeIKnowAbout 的代码称为“样板”。

  a 是 A 的实例,它是Complex(a : A <: Complex) 的子类型,还有 b : B <: Complex。对于 a + b,我这么考虑:

  

  • 如果 A 定义了接受 b 的__add__,那么没问题。

      

  • 如果 A 走到了样板代码分支(译注:else 分支),还从__add__返回一个值的话,那么我们就错过了为 B 定义一个更智能的__radd__的可能性,因此样板应该从__add__返回 NotImplemented。(或者 A 可以不实现__add__)

      

  • 然后 B 的__radd__的机会来了。如果它接受 a,那么没问题。

      

  • 如果它走到样板分支上,就没有办法了,因此需要有默认的实现。

      

  • 如果 B <: A,则 Python 会在 A.__ add__之前尝试 B.__ radd__。这也可以,因为它是基于 A 而实现的,因此可以在委派给 Complex 之前处理这些实例。

      

如果 A <: Complex 和 B <: Real 没有其它关系,则合适的共享操作是内置复数的操作,它们的__radd__都在其中,因此 a + b == b + a。(译注:这几段没看太明白,可能译得不对)

  被拒绝的方案

  本 PEP 的初始版本定义了一个被 Haskell Numeric Prelude 所启发的代数层次结构,其中包括 MonoidUnderPlus、AdditiveGroup、Ring 和 Field,并在得到数字之前,还有其它几种可能的代数类型。

  我们原本希望这对使用向量和矩阵的人有用,但 NumPy 社区确实对此并不感兴趣,另外我们还遇到了一个问题,即便 x 是 X <: MonoidUnderPlus 的实例,而且 y 是 Y < : MonoidUnderPlus 的实例,x + y 可能还是行不通。

  然后,我们为数字提供了更多的分支结构,包括高斯整数(Gaussian Integer)和 Z/nZ 之类的东西,它们可以是 Complex,但不一定支持“除”之类的操作。

  社区认为这对 Python 来说太复杂了,因此我现在缩小了提案的范围,使其更接近于 Scheme 数字塔。

  十进制类型

  经与作者协商,已决定目前不将 Decimal 类型作为数字塔的一部分。

  

更多相关免费学习推荐:python教程

  

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: