99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁(yè)精彩閱讀python 中的數(shù)字到底是什么?
python 中的數(shù)字到底是什么?
2020-09-07
收藏

PEP原文: https://www.python.org/dev/peps/pep-3141

PEP標(biāo)題: PEP 3141 -- A Type Hierarchy for Numbers

PEP作者: Jeffrey Yasskin

創(chuàng)建日期: 2007-04-23

譯者 :豌豆花下貓

來(lái)源:Python貓

PEP翻譯計(jì)劃: https://github.com/chinesehuazhou/peps-cn

花下貓語(yǔ):python 中,不同類(lèi)型的數(shù)字可以直接做算術(shù)運(yùn)算,并不需要作顯式的類(lèi)型轉(zhuǎn)換。但是,它的“隱式類(lèi)型轉(zhuǎn)換”可能跟其它語(yǔ)言不同,因?yàn)?python 中的數(shù)字是一種特殊的對(duì)象,派生自同一個(gè)抽象基類(lèi)。在上一篇文章 中,我們討論到了 Python 數(shù)字的運(yùn)算,然后我想探究“Python 的數(shù)字對(duì)象到底是什么”的話題,所以就翻譯了這篇 PEP,希望對(duì)你也有所幫助。


概要

本提案定義了一種抽象基類(lèi)(ABC)(PEP 3119)的層次結(jié)構(gòu),用來(lái)表示類(lèi)似數(shù)字(number-like)的類(lèi)。它提出了一個(gè) Number :> Complex :> Real :> Rational :> Integral 的層次結(jié)構(gòu),其中 A :> B 表示“A 是 B 的超類(lèi)”。該層次結(jié)構(gòu)受到了 Scheme 的數(shù)字塔(numeric tower)啟發(fā)。(譯注:數(shù)字--復(fù)數(shù)--實(shí)數(shù)--有理數(shù)--整數(shù))

基本原理

以數(shù)字作為參數(shù)的函數(shù)應(yīng)該能夠判定這些數(shù)字的屬性,并且根據(jù)數(shù)字的類(lèi)型,確定是否以及何時(shí)進(jìn)行重載,即基于參數(shù)的類(lèi)型,函數(shù)應(yīng)該是可重載的。

例如,切片要求其參數(shù)為Integrals,而math模塊中的函數(shù)要求其參數(shù)為Real。

規(guī)范

本 PEP 規(guī)定了一組抽象基類(lèi)(Abstract Base Class),并提出了一個(gè)實(shí)現(xiàn)某些方法的通用策略。它使用了來(lái)自于PEP 3119的術(shù)語(yǔ),但是該層次結(jié)構(gòu)旨在對(duì)特定類(lèi)集的任何系統(tǒng)方法都有意義。

標(biāo)準(zhǔn)庫(kù)中的類(lèi)型檢查應(yīng)該使用這些類(lèi),而不是具體的內(nèi)置類(lèi)型。

數(shù)值類(lèi)

我們從 Number 類(lèi)開(kāi)始,它是人們想象的數(shù)字類(lèi)型的模糊概念。此類(lèi)僅用于重載;它不提供任何操作。

class Number(metaclass=ABCMeta): pass

大多數(shù)復(fù)數(shù)(complex number)的實(shí)現(xiàn)都是可散列的,但是如果你需要依賴(lài)它,則必須明確地檢查:此層次結(jié)構(gòu)支持可變的數(shù)。

class Complex(Number):     """Complex defines the operations that work on the builtin complex type.

    In short, those are: conversion to complex, bool(), .real, .imag,
    +, -, *, /, **, abs(), .conjugate(), ==, and !=.

    If it is given heterogenous arguments, and doesn't have special
    knowledge about them, it should fall back to the builtin complex
    type as described below.
    """     @abstractmethod
    def __complex__(self):         """Return a builtin complex instance."""     def __bool__(self):         """True if self != 0."""         return self != 0     @abstractproperty
    def real(self):         """Retrieve the real component of this number.

        This should subclass Real.
        """         raise NotImplementedError

    @abstractproperty
    def imag(self):         """Retrieve the real component of this number.

        This should subclass Real.
        """         raise NotImplementedError

    @abstractmethod
    def __add__(self, other):         raise NotImplementedError

    @abstractmethod
    def __radd__(self, other):         raise NotImplementedError

    @abstractmethod
    def __neg__(self):         raise NotImplementedError

    def __pos__(self):         """Coerces self to whatever class defines the method."""         raise NotImplementedError

    def __sub__(self, other):         return self + -other

    def __rsub__(self, other):         return -self + other

    @abstractmethod
    def __mul__(self, other):         raise NotImplementedError

    @abstractmethod
    def __rmul__(self, other):         raise NotImplementedError

    @abstractmethod
    def __div__(self, other):         """a/b; should promote to float or complex when necessary."""         raise NotImplementedError

    @abstractmethod
    def __rdiv__(self, other):         raise NotImplementedError

    @abstractmethod
    def __pow__(self, exponent):         """a**b; should promote to float or complex when necessary."""         raise NotImplementedError

    @abstractmethod
    def __rpow__(self, base):         raise NotImplementedError

    @abstractmethod
    def __abs__(self):         """Returns the Real distance from 0."""         raise NotImplementedError

    @abstractmethod
    def conjugate(self):         """(x+y*i).conjugate() returns (x-y*i)."""         raise NotImplementedError

    @abstractmethod
    def __eq__(self, other):         raise NotImplementedError

    # __ne__ is inherited from object and negates whatever __eq__ does.

Real抽象基類(lèi)表示在實(shí)數(shù)軸上的值,并且支持內(nèi)置的float的操作。實(shí)數(shù)(Real number)是完全有序的,除了 NaN(本 PEP 基本上不考慮它)。

class Real(Complex):     """To Complex, Real adds the operations that work on real numbers.

    In short, those are: conversion to float, trunc(), math.floor(),
    math.ceil(), round(), divmod(), //, %, <, <=, >, and >=.

    Real also provides defaults for some of the derived operations.
    """     # XXX What to do about the __int__ implementation that's     # currently present on float?  Get rid of it?     @abstractmethod
    def __float__(self):         """Any Real can be converted to a native float object."""         raise NotImplementedError

    @abstractmethod
    def __trunc__(self):         """Truncates self to an Integral.

        Returns an Integral i such that:
          * i>=0 iff self>0;
          * abs(i) <= abs(self);
          * for any Integral j satisfying the first two conditions,
            abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
        i.e. "truncate towards 0".
        """         raise NotImplementedError

    @abstractmethod
    def __floor__(self):         """Finds the greatest Integral <= self."""         raise NotImplementedError

    @abstractmethod
    def __ceil__(self):         """Finds the least Integral >= self."""         raise NotImplementedError

    @abstractmethod
    def __round__(self, ndigits:Integral=None):         """Rounds self to ndigits decimal places, defaulting to 0.

        If ndigits is omitted or None, returns an Integral,
        otherwise returns a Real, preferably of the same type as
        self. Types may choose which direction to round half. For
        example, float rounds half toward even.

        """         raise NotImplementedError

    def __divmod__(self, other):         """The pair (self // other, self % other).

        Sometimes this can be computed faster than the pair of
        operations.
        """         return (self // other, self % other)

    def __rdivmod__(self, other):         """The pair (self // other, self % other).

        Sometimes this can be computed faster than the pair of
        operations.
        """         return (other // self, other % self)

    @abstractmethod
    def __floordiv__(self, other):         """The floor() of self/other. Integral."""         raise NotImplementedError

    @abstractmethod
    def __rfloordiv__(self, other):         """The floor() of other/self."""         raise NotImplementedError

    @abstractmethod
    def __mod__(self, other):         """self % other

        See
        https://mail.python.org/pipermail/python-3000/2006-May/001735.html
        and consider using "self/other - trunc(self/other)"
        instead if you're worried about round-off errors.
        """         raise NotImplementedError

    @abstractmethod
    def __rmod__(self, other):         """other % self"""         raise NotImplementedError

    @abstractmethod
    def __lt__(self, other):         """< on Reals defines a total ordering, except perhaps for NaN."""         raise NotImplementedError

    @abstractmethod
    def __le__(self, other):         raise NotImplementedError

    # __gt__ and __ge__ are automatically done by reversing the arguments.     # (But __le__ is not computed as the opposite of __gt__!)     # Concrete implementations of Complex abstract methods.     # Subclasses may override these, but don't have to.     def __complex__(self):         return complex(float(self))

    @property
    def real(self):         return +self

    @property
    def imag(self):         return 0     def conjugate(self):         """Conjugate is a no-op for Reals."""         return +self

我們應(yīng)該整理 Demo/classes/Rat.py,并把它提升為 Rational.py 加入標(biāo)準(zhǔn)庫(kù)。然后它將實(shí)現(xiàn)有理數(shù)(Rational)抽象基類(lèi)。

class Rational(Real, Exact):     """.numerator and .denominator should be in lowest terms."""     @abstractproperty
    def numerator(self):         raise NotImplementedError

    @abstractproperty
    def denominator(self):         raise NotImplementedError

    # Concrete implementation of Real's conversion to float.     # (This invokes Integer.__div__().)     def __float__(self):         return self.numerator / self.denominator

最后是整數(shù)類(lèi):

class Integral(Rational):     """Integral adds a conversion to int and the bit-string operations."""     @abstractmethod
    def __int__(self):         raise NotImplementedError

    def __index__(self):         """__index__() exists because float has __int__()."""         return int(self)

    def __lshift__(self, other):         return int(self) << int(other)

    def __rlshift__(self, other):         return int(other) << int(self)

    def __rshift__(self, other):         return int(self) >> int(other)

    def __rrshift__(self, other):         return int(other) >> int(self)

    def __and__(self, other):         return int(self) & int(other)

    def __rand__(self, other):         return int(other) & int(self)

    def __xor__(self, other):         return int(self) ^ int(other)

    def __rxor__(self, other):         return int(other) ^ int(self)

    def __or__(self, other):         return int(self) | int(other)

    def __ror__(self, other):         return int(other) | int(self)

    def __invert__(self):         return ~int(self)

    # Concrete implementations of Rational and Real abstract methods.     def __float__(self):         """float(self) == float(int(self))"""         return float(int(self))

    @property
    def numerator(self):         """Integers are their own numerators."""         return +self

    @property
    def denominator(self):         """Integers have a denominator of 1."""         return 1

運(yùn)算及__magic__方法的變更

為了支持從 float 到 int(確切地說(shuō),從 Real 到 Integral)的精度收縮,我們提出了以下新的 __magic__ 方法,可以從相應(yīng)的庫(kù)函數(shù)中調(diào)用。所有這些方法都返回 Intergral 而不是 Real。

  1. __trunc__(self):在新的內(nèi)置 trunc(x) 里調(diào)用,它返回從 0 到 x 之間的最接近 x 的 Integral。
  2. __floor__(self):在 math.floor(x) 里調(diào)用,返回最大的 Integral <= x。
  3. __ceil__(self):在 math.ceil(x) 里調(diào)用,返回最小的 Integral > = x。
  4. __round__(self):在 round(x) 里調(diào)用,返回最接近 x 的 Integral ,根據(jù)選定的類(lèi)型作四舍五入。浮點(diǎn)數(shù)將從 3.0 版本起改為向偶數(shù)端四舍五入。(譯注:round(2.5) 等于 2,round(3.5) 等于 4)。它還有一個(gè)帶兩參數(shù)的版本__round__(self, ndigits),被 round(x, ndigits) 調(diào)用,但返回的是一個(gè) Real。

在 2.6 版本中,math.floor、math.ceil 和 round 將繼續(xù)返回浮點(diǎn)數(shù)。

float 的 int() 轉(zhuǎn)換等效于 trunc()。一般而言,int() 的轉(zhuǎn)換首先會(huì)嘗試__int__(),如果找不到,再?lài)L試__trunc__()。

complex.__{divmod, mod, floordiv, int, float}__ 也消失了。提供一個(gè)好的錯(cuò)誤消息來(lái)幫助困惑的搬運(yùn)工會(huì)很好,但更重要的是不出現(xiàn)在 help(complex) 中。

給類(lèi)型實(shí)現(xiàn)者的說(shuō)明

實(shí)現(xiàn)者應(yīng)該注意使相等的數(shù)字相等,并將它們散列為相同的值。如果實(shí)數(shù)有兩個(gè)不同的擴(kuò)展,這可能會(huì)變得微妙。例如,一個(gè)復(fù)數(shù)類(lèi)型可以像這樣合理地實(shí)現(xiàn) hash():

def __hash__(self):
    return hash(complex(self))

但應(yīng)注意所有超出了內(nèi)置復(fù)數(shù)范圍或精度的值。

添加更多數(shù)字抽象基類(lèi)

當(dāng)然,數(shù)字還可能有更多的抽象基類(lèi),如果排除了添加這些數(shù)字的可能性,這會(huì)是一個(gè)糟糕的等級(jí)體系。你可以使用以下方法在 Complex 和 Real 之間添加MyFoo:

class MyFoo(Complex): ...
MyFoo.register(Real)

實(shí)現(xiàn)算術(shù)運(yùn)算

我們希望實(shí)現(xiàn)算術(shù)運(yùn)算,使得在混合模式的運(yùn)算時(shí),要么調(diào)用者知道如何處理兩種參數(shù)類(lèi)型,要么將兩者都轉(zhuǎn)換為最接近的內(nèi)置類(lèi)型,并以此進(jìn)行操作。

對(duì)于 Integral 的子類(lèi)型,這意味著__add__和__radd__應(yīng)該被定義為:

class MyIntegral(Integral):     def __add__(self, other):         if isinstance(other, MyIntegral):
            return do_my_adding_stuff(self, other)
        elif isinstance(other, OtherTypeIKnowAbout):
            return do_my_other_adding_stuff(self, other)
        else:
            return NotImplemented     def __radd__(self, other):         if isinstance(other, MyIntegral):
            return do_my_adding_stuff(other, self)
        elif isinstance(other, OtherTypeIKnowAbout):
            return do_my_other_adding_stuff(other, self)
        elif isinstance(other, Integral):
            return int(other) + int(self)
        elif isinstance(other, Real):
            return float(other) + float(self)
        elif isinstance(other, Complex):
            return complex(other) + complex(self)
        else:
            return NotImplemented

對(duì) Complex 的子類(lèi)進(jìn)行混合類(lèi)型操作有 5 種不同的情況。我把以上所有未包含 MyIntegral 和 OtherTypeIKnowAbout 的代碼稱(chēng)為“樣板”。

a 是 A 的實(shí)例,它是Complex(a : A <: Complex) 的子類(lèi)型,還有 b : B <: Complex。對(duì)于 a + b,我這么考慮:

  1. 如果 A 定義了接受 b 的__add__,那么沒(méi)問(wèn)題。
  2. 如果 A 走到了樣板代碼分支(譯注:else 分支),還從__add__返回一個(gè)值的話,那么我們就錯(cuò)過(guò)了為 B 定義一個(gè)更智能的__radd__的可能性,因此樣板應(yīng)該從__add__返回 NotImplemented。(或者 A 可以不實(shí)現(xiàn)__add__)
  3. 然后 B 的__radd__的機(jī)會(huì)來(lái)了。如果它接受 a,那么沒(méi)問(wèn)題。
  4. 如果它走到樣板分支上,就沒(méi)有辦法了,因此需要有默認(rèn)的實(shí)現(xiàn)。
  5. 如果 B <: A,則 Python 會(huì)在 A.__ add__之前嘗試 B.__ radd__。這也可以,因?yàn)樗腔?A 而實(shí)現(xiàn)的,因此可以在委派給 Complex 之前處理這些實(shí)例。

如果 A <: Complex 和 B <: Real 沒(méi)有其它關(guān)系,則合適的共享操作是內(nèi)置復(fù)數(shù)的操作,它們的__radd__都在其中,因此 a + b == b + a。(譯注:這幾段沒(méi)看太明白,可能譯得不對(duì))

被拒絕的方案

本 PEP 的初始版本定義了一個(gè)被 Haskell Numeric Prelude 所啟發(fā)的代數(shù)層次結(jié)構(gòu),其中包括 MonoidUnderPlus、AdditiveGroup、Ring 和 Field,并在得到數(shù)字之前,還有其它幾種可能的代數(shù)類(lèi)型。

我們?cè)鞠M@對(duì)使用向量和矩陣的人有用,但 NumPy 社區(qū)確實(shí)對(duì)此并不感興趣,另外我們還遇到了一個(gè)問(wèn)題,即便 x 是 X <: MonoidUnderPlus 的實(shí)例,而且 y 是 Y < : MonoidUnderPlus 的實(shí)例,x + y 可能還是行不通。

然后,我們?yōu)閿?shù)字提供了更多的分支結(jié)構(gòu),包括高斯整數(shù)(Gaussian Integer)和 Z/nZ 之類(lèi)的東西,它們可以是 Complex,但不一定支持“除”之類(lèi)的操作。

社區(qū)認(rèn)為這對(duì) Python 來(lái)說(shuō)太復(fù)雜了,因此我現(xiàn)在縮小了提案的范圍,使其更接近于 Scheme 數(shù)字塔。

十進(jìn)制類(lèi)型

經(jīng)與作者協(xié)商,已決定目前不將 Decimal 類(lèi)型作為數(shù)字塔的一部分。

參考文獻(xiàn)

1、抽象基類(lèi)簡(jiǎn)介:http://www.python.org/dev/peps/pep-3119/

2、可能是 Python 3 的類(lèi)樹(shù)?Bill Janssen 的 Wiki 頁(yè)面:http://wiki.python.org/moin/AbstractBaseClasses

3、NumericPrelude:數(shù)字類(lèi)型類(lèi)的實(shí)驗(yàn)性備選層次結(jié)構(gòu):http://darcs.haskell.org/numericprelude/docs/html/index.html

4、Scheme 數(shù)字塔:https://groups.csail.mit.edu/mac/ftpdir/scheme-reports/r5rs-html/r5rs_8.html#SEC50

(譯注:在譯完之后,我才發(fā)現(xiàn)“PEP中文翻譯計(jì)劃”已收錄過(guò)一篇譯文,有些地方譯得不盡相同,讀者們可點(diǎn)擊閱讀原文,比對(duì)閱讀。)

致謝

感謝 Neal Norwitz 最初鼓勵(lì)我編寫(xiě)此 PEP,感謝 Travis Oliphant 指出 numpy 社區(qū)并不真正關(guān)心代數(shù)概念,感謝 Alan Isaac 提醒我 Scheme 已經(jīng)做到了,以及感謝 Guido van Rossum 和郵件組里的其他人幫忙完善了這套概念。

數(shù)據(jù)分析咨詢(xún)請(qǐng)掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢(xún)
客服在線
立即咨詢(xún)
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對(duì)象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶(hù)后臺(tái)檢測(cè)極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說(shuō)明請(qǐng)參見(jiàn):http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請(qǐng)輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請(qǐng)輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }