国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

SICP Python 描述 2.7 泛用方法

leanote / 657人閱讀

摘要:使用消息傳遞,我們就能使抽象數據類型直接擁有行為。構造器以類似的方式實現它在參數上調用了叫做的方法。抽象數據類型允許我們在數據表示和用于操作數據的函數之間構造界限。

2.7 泛用方法

來源:2.7 Generic Operations

譯者:飛龍

協議:CC BY-NC-SA 4.0

這一章中我們引入了復合數據類型,以及由構造器和選擇器實現的數據抽象機制。使用消息傳遞,我們就能使抽象數據類型直接擁有行為。使用對象隱喻,我們可以將數據的表示和用于操作數據的方法綁定在一起,從而使數據驅動的程序模塊化,并帶有局部狀態。

但是,我們仍然必須展示,我們的對象系統允許我們在大型程序中靈活組合不同類型的對象。點運算符的消息傳遞僅僅是一種用于使用多個對象構建組合表達式的方式。這一節中,我們會探索一些用于組合和操作不同類型對象的方式。

2.7.1 字符串轉換

我們在這一章最開始說,對象值的行為應該類似它所表達的數據,包括產生它自己的字符串表示。數據值的字符串表示在類似 Python 的交互式語言中尤其重要,其中“讀取-求值-打印”的循環需要每個值都擁有某種字符串表示形式。

字符串值為人們的信息交流提供了基礎的媒介。字符序列可以在屏幕上渲染,打印到紙上,大聲朗讀,轉換為盲文,或者以莫爾茲碼廣播。字符串對編程而言也非常基礎,因為它們可以表示 Python 表達式。對于一個對象,我們可能希望生成一個字符串,當作為 Python 表達式解釋時,求值為等價的對象。

Python 規定,所有對象都應該能夠產生兩種不同的字符串表示:一種是人類可解釋的文本,另一種是 Python 可解釋的表達式。字符串的構造函數str返回人類可讀的字符串。在可能的情況下,repr函數返回一個 Python 表達式,它可以求值為等價的對象。repr的文檔字符串解釋了這個特性:

repr(object) -> string

Return the canonical string representation of the object.
For most object types, eval(repr(object)) == object.

在表達式的值上調用repr的結果就是 Python 在交互式會話中打印的東西。

>>> 12e12
12000000000000.0
>>> print(repr(12e12))
12000000000000.0

在不存在任何可以求值為原始值的表達式的情況中,Python 會產生一個代理:

>>> repr(min)
""

str構造器通常與repr相同,但是有時會提供更加可解釋的文本表示。例如,我們可以看到strrepr對于日期的不同:

>>> from datetime import date
>>> today = date(2011, 9, 12)
>>> repr(today)
"datetime.date(2011, 9, 12)"
>>> str(today)
"2011-09-12"

repr函數的定義出現了新的挑戰:我們希望它對所有數據類型都正確應用,甚至是那些在repr實現時還不存在的類型。我們希望它像一個多態函數,可以作用于許多(多)不同形式(態)的數據。

消息傳遞提供了這個問題的解決方案:repr函數在參數上調用叫做__repr__的函數。

>>> today.__repr__()
"datetime.date(2011, 9, 12)"

通過在用戶定義的類上實現同一方法,我們就可以將repr的適用性擴展到任何我們以后創建的類。這個例子強調了消息傳遞的另一個普遍的好處:就是它提供了一種機制,用于將現有函數的職責范圍擴展到新的對象。

str構造器以類似的方式實現:它在參數上調用了叫做__str__的方法。

>>> today.__str__()
"2011-09-12"

這些多態函數是一個更普遍原則的例子:特定函數應該作用于多種數據類型。這里舉例的消息傳遞方法僅僅是多態函數實現家族的一員。本節剩下的部分會探索一些備選方案。

2.7.2 多重表示

使用對象或函數的數據抽象是用于管理復雜性的強大工具。抽象數據類型允許我們在數據表示和用于操作數據的函數之間構造界限。但是,在大型程序中,對于程序中的某種數據類型,提及“底層表示”可能不總是有意義。首先,一個數據對象可能有多種實用的表示,而且我們可能希望設計能夠處理多重表示的系統。

為了選取一個簡單的示例,復數可以用兩種幾乎等價的方式來表示:直角坐標(虛部和實部)以及極坐標(模和角度)。有時直角坐標形式更加合適,而有時極坐標形式更加合適。復數以兩種方式表示,而操作復數的函數可以處理每種表示,這樣一個系統確實比較合理。

更重要的是,大型軟件系統工程通常由許多人設計,并花費大量時間,需求的主題隨時間而改變。在這樣的環境中,每個人都事先同意數據表示的方案是不可能的。除了隔離使用和表示的數據抽象的界限,我們需要隔離不同設計方案的界限,以及允許不同方案在一個程序中共存。進一步,由于大型程序通常通過組合已存在的模塊創建,這些模塊會多帶帶設計,我們需要一種慣例,讓程序員將模塊遞增地組合為大型系統。也就是說,不需要重復設計或實現這些模塊。

我們以最簡單的復數示例開始。我們會看到,消息傳遞在維持“復數”對象的抽象概念時,如何讓我們為復數的表示設計出分離的直角坐標和極坐標表示。我們會通過使用泛用選擇器為復數定義算數函數(add_complexmul_complex)來完成它。泛用選擇器可訪問復數的一部分,獨立于數值表示的方式。所產生的復數系統包含兩種不同類型的抽象界限。它們隔離了高階操作和低階表示。此外,也有一個垂直的界限,它使我們能夠獨立設計替代的表示。

作為邊注,我們正在開發一個系統,它在復數上執行算數運算,作為一個簡單但不現實的使用泛用操作的例子。復數類型實際上在 Python 中已經內建了,但是這個例子中我們仍然自己實現。

就像有理數那樣,復數可以自然表示為偶對。復數集可以看做帶有兩個正交軸,實數軸和虛數軸的二維空間。根據這個觀點,復數z = x + y * i(其中i*i = -1)可以看做平面上的點,它的實數為x,虛部為y。復數加法涉及到將它們的實部和虛部相加。

對復數做乘法時,將復數以極坐標表示為模和角度更加自然。兩個復數的乘積是,將一個復數按照另一個的長度作為因數拉伸,之后按照另一個的角度來旋轉它的所得結果。

所以,復數有兩種不同表示,它們適用于不同的操作。然而,從一些人編寫使用復數的程序的角度來看,數據抽象的原則表明,所有操作復數的運算都應該可用,無論計算機使用了哪個表示。

接口。消息傳遞并不僅僅提供用于組裝行為和數據的方式。它也允許不同的數據類型以不同方式響應相同消息。來自不同對象,產生相似行為的共享消息是抽象的有力手段。

像之前看到的那樣,抽象數據類型由構造器、選擇器和額外的行為條件定義。與之緊密相關的概念是接口,它是共享消息的集合,帶有它們含義的規定。響應__repr____str__特殊方法的對象都實現了通用的接口,它們可以表示為字符串。

在復數的例子中,接口需要實現由四個消息組成的算數運算:realimagmagnitudeangle。我們可以使用這些消息實現加法和乘法。

我們擁有兩種復數的抽象數據類型,它們的構造器不同。

ComplexRI從實部和虛部構造復數。

ComplexMA從模和角度構造復數。

使用這些消息和構造器,我們可以實現復數算數:

>>> def add_complex(z1, z2):
        return ComplexRI(z1.real + z2.real, z1.imag + z2.imag)
>>> def mul_complex(z1, z2):
        return ComplexMA(z1.magnitude * z2.magnitude, z1.angle + z2.angle)

術語“抽象數據類型”(ADT)和“接口”的關系是微妙的。ADT 包含構建復雜數據類的方式,以單元操作它們,并且可以選擇它們的組件。在面向對象系統中,ADT 對應一個類,雖然我們已經看到對象系統并不需要實現 ADT。接口是一組與含義關聯的消息,并且它可能包含選擇器,也可能不包含。概念上,ADT 描述了一類東西的完整抽象表示,而接口規定了可能在許多東西之間共享的行為。

屬性(Property)。我們希望交替使用復數的兩種類型,但是對于每個數值來說,儲存重復的信息比較浪費。我們希望儲存實部-虛部的表示或模-角度的表示之一。

Python 擁有一個簡單的特性,用于從零個參數的函數憑空計算屬性(Attribute)。@property裝飾器允許函數不使用標準調用表達式語法來調用。根據實部和虛部的復數實現展示了這一點。

>>> from math import atan2
>>> class ComplexRI(object):
        def __init__(self, real, imag):
            self.real = real
            self.imag = imag
        @property
        def magnitude(self):
            return (self.real ** 2 + self.imag ** 2) ** 0.5
        @property
        def angle(self):
            return atan2(self.imag, self.real)
        def __repr__(self):
            return "ComplexRI({0}, {1})".format(self.real, self.imag)

第二種使用模和角度的實現提供了相同接口,因為它響應同一組消息。

>>> from math import sin, cos
>>> class ComplexMA(object):
        def __init__(self, magnitude, angle):
            self.magnitude = magnitude
            self.angle = angle
        @property
        def real(self):
            return self.magnitude * cos(self.angle)
        @property
        def imag(self):
            return self.magnitude * sin(self.angle)
        def __repr__(self):
            return "ComplexMA({0}, {1})".format(self.magnitude, self.angle)

實際上,我們的add_complexmul_complex實現并沒有完成;每個復數類可以用于任何算數函數的任何參數。對象系統不以任何方式顯式連接(例如通過繼承)這兩種復數類型,這需要給個注解。我們已經通過在兩個類之間共享一組通用的消息和接口,實現了復數抽象。

>>> from math import pi
>>> add_complex(ComplexRI(1, 2), ComplexMA(2, pi/2))
ComplexRI(1.0000000000000002, 4.0)
>>> mul_complex(ComplexRI(0, 1), ComplexRI(0, 1))
ComplexMA(1.0, 3.141592653589793)

編碼多種表示的接口擁有良好的特性。用于每個表示的類可以獨立開發;它們只需要遵循它們所共享的屬性名稱。這個接口同時是遞增的。如果另一個程序員希望向相同程序添加第三個復數表示,它們只需要使用相同屬性創建另一個類。

特殊方法。內建的算數運算符可以以一種和repr相同的方式擴展;它們是特殊的方法名稱,對應 Python 的算數、邏輯和序列運算的運算符。

為了使我們的代碼更加易讀,我們可能希望在執行復數加法和乘法時直接使用+*運算符。將下列方法添加到兩個復數類中,這會讓這些運算符,以及opertor模塊中的addmul函數可用。

>>> ComplexRI.__add__ = lambda self, other: add_complex(self, other)
>>> ComplexMA.__add__ = lambda self, other: add_complex(self, other)
>>> ComplexRI.__mul__ = lambda self, other: mul_complex(self, other)
>>> ComplexMA.__mul__ = lambda self, other: mul_complex(self, other)

現在,我們可以對我們的自定義類使用中綴符號。

>>> ComplexRI(1, 2) + ComplexMA(2, 0)
ComplexRI(3.0, 2.0)
>>> ComplexRI(0, 1) * ComplexRI(0, 1)
ComplexMA(1.0, 3.141592653589793)

擴展閱讀。為了求解含有+運算符的表達式,Python 會檢查表達式的左操作數和右操作數上的特殊方法。首先,Python 會檢查左操作數的__add__方法,之后檢查右操作數的__radd__方法。如果二者之一被發現,這個方法會以另一個操作數的值作為參數調用。

在 Python 中求解含有任何類型的運算符的表達值具有相似的協議,這包括切片符號和布爾運算符。Python 文檔列出了完整的運算符的方法名稱。Dive into Python 3 的特殊方法名稱一章描述了許多用于 Python 解釋器的細節。

2.7.3 泛用函數

我們的復數實現創建了兩種數據類型,它們對于add_complexmul_complex函數能夠互相轉換。現在我們要看看如何使用相同的概念,不僅僅定義不同表示上的泛用操作,也能用來定義不同種類、并且不共享通用結構的參數上的泛用操作。

我們到目前為止已定義的操作將不同的數據類型獨立對待。所以,存在用于加法的獨立的包,比如兩個有理數或者兩個復數。我們沒有考慮到的是,定義類型界限之間的操作很有意義,比如將復數與有理數相加。我們經歷了巨大的痛苦,引入了程序中各個部分的界限,便于讓它們可被獨立開發和理解。

我們希望以某種精確控制的方式引入跨類型的操作。便于在不嚴重違反抽象界限的情況下支持它們。在我們希望的結果之間可能有些矛盾:我們希望能夠將有理數與復數相加,也希望能夠使用泛用的add函數,正確處理所有數值類型。同時,我們希望隔離復數和有理數的細節,來維持程序的模塊化。

讓我們使用 Python 內建的對象系統重新編寫有理數的實現。像之前一樣,我們在較低層級將有理數儲存為分子和分母。

>>> from fractions import gcd
>>> class Rational(object):
        def __init__(self, numer, denom):
            g = gcd(numer, denom)
            self.numer = numer // g
            self.denom = denom // g
        def __repr__(self):
            return "Rational({0}, {1})".format(self.numer, self.denom)

這個新的實現中的有理數的加法和乘法和之前類似。

>>> def add_rational(x, y):
        nx, dx = x.numer, x.denom
        ny, dy = y.numer, y.denom
        return Rational(nx * dy + ny * dx, dx * dy)
>>> def mul_rational(x, y):
        return Rational(x.numer * y.numer, x.denom * y.denom)

類型分發。一種處理跨類型操作的方式是為每種可能的類型組合設計不同的函數,操作可用于這種類型。例如,我們可以擴展我們的復數實現,使其提供函數用于將復數與有理數相加。我們可以使用叫做類型分發的機制更通用地提供這個功能。

類型分發的概念是,編寫一個函數,首先檢測接受到的參數類型,之后執行適用于這種類型的代碼。Python 中,對象類型可以使用內建的type函數來檢測。

>>> def iscomplex(z):
        return type(z) in (ComplexRI, ComplexMA)
>>> def isrational(z):
        return type(z) == Rational

這里,我們依賴一個事實,每個對象都知道自己的類型,并且我們可以使用Python 的type函數來獲取類型。即使type函數不可用,我們也能根據RationalComplexRIComplexMA來實現iscomplexisrational

現在考慮下面的add實現,它顯式檢查了兩個參數的類型。我們不會在這個例子中顯式使用 Python 的特殊方法(例如__add__)。

>>> def add_complex_and_rational(z, r):
            return ComplexRI(z.real + r.numer/r.denom, z.imag)
>>> def add(z1, z2):
        """Add z1 and z2, which may be complex or rational."""
        if iscomplex(z1) and iscomplex(z2):
            return add_complex(z1, z2)
        elif iscomplex(z1) and isrational(z2):
            return add_complex_and_rational(z1, z2)
        elif isrational(z1) and iscomplex(z2):
            return add_complex_and_rational(z2, z1)
        else:
            return add_rational(z1, z2)

這個簡單的類型分發方式并不是遞增的,它使用了大量的條件語句。如果另一個數值類型包含在程序中,我們需要使用新的語句重新實現add

我們可以創建更靈活的add實現,通過以字典實現類型分發。要想擴展add的靈活性,第一步是為我們的類創建一個tag集合,抽離兩個復數集合的實現。

>>> def type_tag(x):
        return type_tag.tags[type(x)]
>>> type_tag.tags = {ComplexRI: "com", ComplexMA: "com", Rational: "rat"}

下面,我們使用這些類型標簽來索引字典,字典中儲存了數值加法的不同方式。字典的鍵是類型標簽的元素,值是類型特定的加法函數。

>>> def add(z1, z2):
        types = (type_tag(z1), type_tag(z2))
        return add.implementations[types](z1, z2)

這個基于字典的分發方式是遞增的,因為add.implementationstype_tag.tags總是可以擴展。任何新的數值類型可以將自己“安裝”到現存的系統中,通過向這些字典添加新的條目。

當我們向系統引入一些復雜性時,我們現在擁有了泛用、可擴展的add函數,可以處理混合類型。

>>> add(ComplexRI(1.5, 0), Rational(3, 2))
ComplexRI(3.0, 0)
>>> add(Rational(5, 3), Rational(1, 2))
Rational(13, 6)

數據導向編程。我們基于字典的add實現并不是特定于加法的;它不包含任何加法的直接邏輯。它只實現了加法操作,因為我們碰巧將implementations字典和函數放到一起來執行加法。

更通用的泛用算數操作版本會將任意運算符作用于任意類型,并且使用字典來儲存多種組合的實現。這個完全泛用的實現方法的方式叫做數據導向編程。在我們這里,我們可以實現泛用加法和乘法,而不帶任何重復的邏輯。

>>> def apply(operator_name, x, y):
        tags = (type_tag(x), type_tag(y))
        key = (operator_name, tags)
        return apply.implementations[key](x, y)

在泛用的apply函數中,鍵由操作數的名稱(例如add),和參數類型標簽的元組構造。我們下面添加了對復數和有理數的乘法支持。

>>> def mul_complex_and_rational(z, r):
        return ComplexMA(z.magnitude * r.numer / r.denom, z.angle)
>>> mul_rational_and_complex = lambda r, z: mul_complex_and_rational(z, r)
>>> apply.implementations = {("mul", ("com", "com")): mul_complex,
                             ("mul", ("com", "rat")): mul_complex_and_rational,
                             ("mul", ("rat", "com")): mul_rational_and_complex,
                             ("mul", ("rat", "rat")): mul_rational}

我們也可以使用字典的update方法,從add中將加法實現添加到apply

>>> adders = add.implementations.items()
>>> apply.implementations.update({("add", tags):fn for (tags, fn) in adders})

既然已經在單一的表中支持了 8 種不同的實現,我們可以用它來更通用地操作有理數和復數。

>>> apply("add", ComplexRI(1.5, 0), Rational(3, 2))
ComplexRI(3.0, 0)
>>> apply("mul", Rational(1, 2), ComplexMA(10, 1))
ComplexMA(5.0, 1)

這個數據導向的方式管理了跨類型運算符的復雜性,但是十分麻煩。使用這個一個系統,引入新類型的開銷不僅僅是為類型編寫方法,還有實現跨類型操作的函數的構造和安裝。這個負擔比起定義類型本身的操作需要更多代碼。

當類型分發機制和數據導向編程的確能創造泛用函數的遞增實現時,它們就不能有效隔離實現的細節。獨立數值類型的實現者需要在編程跨類型操作時考慮其他類型。組合有理數和復數嚴格上并不是每種類型的范圍。在類型中制定一致的責任分工政策,在帶有多種類型和跨類型操作的系統設計中是大勢所趨。

強制轉換。在完全不相關的類型執行完全不相關的操作的一般情況中,實現顯式的跨類型操作,盡管可能非常麻煩,是人們所希望的最佳方案。幸運的是,我們有時可以通過利用類型系統中隱藏的額外結構來做得更好。不同的數據類通常并不是完全獨立的,可能有一些方式,一個類型的對象通過它會被看做另一種類型的對象。這個過程叫做強制轉換。例如,如果我們被要求將一個有理數和一個復數通過算數來組合,我們可以將有理數看做虛部為零的復數。通過這樣做,我們將問題轉換為兩個復數組合的問題,這可以通過add_complexmul_complex由經典的方法處理。

通常,我們可以通過設計強制轉換函數來實現這個想法。強制轉換函數將一個類型的對象轉換為另一個類型的等價對象。這里是一個典型的強制轉換函數,它將有理數轉換為虛部為零的復數。

>>> def rational_to_complex(x):
        return ComplexRI(x.numer/x.denom, 0)

現在,我們可以定義強制轉換函數的字典。這個字典可以在更多的數值類型引入時擴展。

>>> coercions = {("rat", "com"): rational_to_complex}

任意類型的數據對象不可能轉換為每個其它類型的對象。例如,沒有辦法將任意的復數強制轉換為有理數,所以在coercions字典中應該沒有這種轉換的實現。

使用coercions字典,我們可以編寫叫做coerce_apply的函數,它試圖將參數強制轉換為相同類型的值,之后僅僅調用運算符。coerce_apply 的實現字典不包含任何跨類型運算符的實現。

>>> def coerce_apply(operator_name, x, y):
        tx, ty = type_tag(x), type_tag(y)
        if tx != ty:
            if (tx, ty) in coercions:
                tx, x = ty, coercions[(tx, ty)](x)
            elif (ty, tx) in coercions:
                ty, y = tx, coercions[(ty, tx)](y)
            else:
                return "No coercion possible."
        key = (operator_name, tx)
        return coerce_apply.implementations[key](x, y)

coerce_applyimplementations僅僅需要一個類型標簽,因為它們假設兩個值都共享相同的類型標簽。所以,我們僅僅需要四個實現來支持復數和有理數上的泛用算數。

>>> coerce_apply.implementations = {("mul", "com"): mul_complex,
                                    ("mul", "rat"): mul_rational,
                                    ("add", "com"): add_complex,
                                    ("add", "rat"): add_rational}

就地使用這些實現,coerce_apply 可以代替apply

>>> coerce_apply("add", ComplexRI(1.5, 0), Rational(3, 2))
ComplexRI(3.0, 0)
>>> coerce_apply("mul", Rational(1, 2), ComplexMA(10, 1))
ComplexMA(5.0, 1.0)

這個強制轉換的模式比起顯式定義跨類型運算符的方式具有優勢。雖然我們仍然需要編程強制轉換函數來關聯類型,我們僅僅需要為每對類型編寫一個函數,而不是為每個類型組合和每個泛用方法編寫不同的函數。我們所期望的是,類型間的合理轉換僅僅依賴于類型本身,而不是要調用的特定操作。

強制轉換的擴展會帶來進一步的優勢。一些更復雜的強制轉換模式并不僅僅試圖將一個類型強制轉換為另一個,而是將兩個不同類型強制轉換為第三個。想一想菱形和長方形:每個都不是另一個的特例,但是兩個都可以看做平行四邊形。另一個強制轉換的擴展是迭代的強制轉換,其中一個數據類型通過媒介類型被強制轉換為另一種。一個整數可以轉換為一個實數,通過首先轉換為有理數,接著將有理數轉換為實數。這種方式的鏈式強制轉換降低了程序所需的轉換函數總數。

雖然它具有優勢,強制轉換也有潛在的缺陷。例如,強制轉換函數在調用時會丟失信息。在我們的例子中,有理數是精確表示,但是當它們轉換為復數時會變得近似。

一些編程語言擁有內建的強制轉換函數。實際上,Python 的早期版本擁有對象上的__coerce__特殊方法。最后,內建強制轉換系統的復雜性并不能支持它的使用,所以被移除了。反之,特定的操作按需強制轉換它們的參數。運算符被實現為用戶定義類上的特殊方法,比如__add____mul__。這完全取決于你,取決于用戶來決定是否使用類型分發,數據導向編程,消息傳遞,或者強制轉換來在你的程序中實現泛用函數。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/38164.html

相關文章

  • SICP Python 描述 第三章 計算機程序的構造和解釋 3.1 引言

    摘要:為通用語言設計解釋器的想法可能令人畏懼。但是,典型的解釋器擁有簡潔的通用結構兩個可變的遞歸函數,第一個求解環境中的表達式,第二個在參數上調用函數。這一章接下來的兩節專注于遞歸函數和數據結構,它們是理解解釋器設計的基礎。 3.1 引言 來源:3.1 Introduction 譯者:飛龍 協議:CC BY-NC-SA 4.0 第一章和第二章描述了編程的兩個基本元素:數據和函數之間的...

    v1 評論0 收藏0
  • SICP Python 描述 2.3 序列

    摘要:序列不是特定的抽象數據類型,而是不同類型共有的一組行為。不像抽象數據類型,我們并沒有闡述如何構造序列。這兩個選擇器和一個構造器,以及一個常量共同實現了抽象數據類型的遞歸列表。 2.3 序列 來源:2.3 Sequences 譯者:飛龍 協議:CC BY-NC-SA 4.0 序列是數據值的順序容器。不像偶對只有兩個元素,序列可以擁有任意(但是有限)個有序元素。 序列在計算機科學中...

    AlexTuan 評論0 收藏0
  • SICP Python 描述 第二章 使用對象構建抽象 2.1 引言

    摘要:對象表示信息,但是同時和它們所表示的抽象概念行為一致。通過綁定行為和信息,對象提供了可靠獨立的日期抽象。名稱來源于實數在中表示的方式浮點表示。另一方面,對象可以表示很大范圍內的分數,但是不能表示所有有理數。 2.1 引言 來源:2.1 Introduction 譯者:飛龍 協議:CC BY-NC-SA 4.0 在第一章中,我們專注于計算過程,以及程序設計中函數的作用。我們看到了...

    phoenixsky 評論0 收藏0
  • SICP Python 描述 1.4 實踐指南:函數的藝術

    摘要:實踐指南函數的藝術來源譯者飛龍協議函數是所有程序的要素,無論規模大小,并且在編程語言中作為我們表達計算過程的主要媒介。目前為止,我們討論了函數的形式特性,以及它們如何使用。第一行描述函數的任務。 1.4 實踐指南:函數的藝術 來源:1.4 Practical Guidance: The Art of the Function 譯者:飛龍 協議:CC BY-NC-SA 4.0 函...

    lemon 評論0 收藏0
  • SICP Python描述 1.1 引言

    摘要:另一個賦值語句將名稱關聯到出現在莎士比亞劇本中的所有去重詞匯的集合,總計個。表達式是一個復合表達式,計算出正序或倒序出現的莎士比亞詞匯集合。在意圖上并沒有按照莎士比亞或者回文來設計,但是它極大的靈活性讓我們用極少的代碼處理大量文本。 1.1 引言 來源:1.1 Introduction 譯者:飛龍 協議:CC BY-NC-SA 4.0 計算機科學是一個極其寬泛的學科。全球的分布...

    xumenger 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<