首页IT科技python中数字的类型(认识python中的数字)

python中数字的类型(认识python中的数字)

时间2025-06-29 02:40:07分类IT科技浏览4036
导读:概要...

概要

本提案定义了一种抽象基类(ABC)(PEP 3119)的层次结构            ,用来表示类似数字(number-like)的类            。它提出了一个 Number :> Complex :> Real :> Rational :> Integral 的层次结构                  ,其中 A :> B 表示“A 是 B 的超类            ”                  。该层次结构受到了 Scheme 的数字塔(numeric tower)启发      。(译注:数字--复数--实数--有理数--整数)

基本原理

以数字作为参数的函数应该能够判定这些数字的属性      ,并且根据数字的类型      ,确定是否以及何时进行重载                  ,即基于参数的类型            ,函数应该是可重载的      。

例如      ,切片要求其参数为Integrals                  ,而math模块中的函数要求其参数为Real                  。

规范

本 PEP 规定了一组抽象基类(Abstract Base Class)            ,并提出了一个实现某些方法的通用策略            。它使用了来自于PEP 3119的术语,但是该层次结构旨在对特定类集的任何系统方法都有意义      。

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

数值类

我们从 Number 类开始                  ,它是人们想象的数字类型的模糊概念            。此类仅用于重载;它不提供任何操作。

classNumber(metaclass=ABCMeta):pass

大多数复数(complex number)的实现都是可散列的,但是如果你需要依赖它            ,则必须明确地检查:此层次结构支持可变的数                  。

classComplex(Number): """Complexdefinestheoperationsthatworkonthebuiltincomplextype. Inshort,thoseare:conversiontocomplex,bool(),.real,.imag, +,-,*,/,**,abs(),.conjugate(),==,and!=. Ifitisgivenheterogenousarguments,anddoesnthavespecial knowledgeaboutthem,itshouldfallbacktothebuiltincomplex typeasdescribedbelow. """ @abstractmethod def__complex__(self): """Returnabuiltincomplexinstance.""" def__bool__(self): """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__implementationthats #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)" insteadifyoureworriedaboutround-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,butdonthaveto. 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 #ConcreteimplementationofRealsconversiontofloat. #(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 类型作为数字塔的一部分                  。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
yolo训练太慢(Yolov7-pose 训练body+foot关键点) 动漫中能控制人的人物(妙啊!动画还可以这样控制?)