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

資訊專欄INFORMATION COLUMN

SICP Python 描述 2.6 實(shí)現(xiàn)類和對(duì)象

chenjiang3 / 381人閱讀

摘要:以這種方式實(shí)現(xiàn)對(duì)象系統(tǒng)的目的是展示使用對(duì)象隱喻并不需要特殊的編程語言。我們的實(shí)現(xiàn)并不遵循類型系統(tǒng)的明確規(guī)定。反之,它為實(shí)現(xiàn)對(duì)象隱喻的核心功能而設(shè)計(jì)。是分發(fā)字典,它響應(yīng)消息和。

2.6 實(shí)現(xiàn)類和對(duì)象

來源:2.6 Implementing Classes and Objects

譯者:飛龍

協(xié)議:CC BY-NC-SA 4.0

在使用面向?qū)ο缶幊谭妒綍r(shí),我們使用對(duì)象隱喻來指導(dǎo)程序的組織。數(shù)據(jù)表示和操作的大部分邏輯都表達(dá)在類的定義中。在這一節(jié)中,我們會(huì)看到,類和對(duì)象本身可以使用函數(shù)和字典來表示。以這種方式實(shí)現(xiàn)對(duì)象系統(tǒng)的目的是展示使用對(duì)象隱喻并不需要特殊的編程語言。即使編程語言沒有面向?qū)ο笙到y(tǒng),程序照樣可以面向?qū)ο蟆?/p>

為了實(shí)現(xiàn)對(duì)象,我們需要拋棄點(diǎn)運(yùn)算符(它需要語言的內(nèi)建支持),并創(chuàng)建分發(fā)字典,它的行為和內(nèi)建對(duì)象系統(tǒng)的元素差不多。我們已經(jīng)看到如何通過分發(fā)字典實(shí)現(xiàn)消息傳遞行為。為了完整實(shí)現(xiàn)對(duì)象系統(tǒng),我們需要在實(shí)例、類和基類之間發(fā)送消息,它們?nèi)慷际呛袑傩缘淖值洹?/p>

我們不會(huì)實(shí)現(xiàn)整個(gè) Python 對(duì)象系統(tǒng),它包含這篇文章沒有涉及到的特性(比如元類和靜態(tài)方法)。我們會(huì)專注于用戶定義的類,不帶有多重繼承和內(nèi)省行為(比如返回實(shí)例的類)。我們的實(shí)現(xiàn)并不遵循 Python 類型系統(tǒng)的明確規(guī)定。反之,它為實(shí)現(xiàn)對(duì)象隱喻的核心功能而設(shè)計(jì)。

2.6.1 實(shí)例

我們從實(shí)例開始。實(shí)例擁有具名屬性,例如賬戶余額,它可以被設(shè)置或獲取。我們使用分發(fā)字典來實(shí)現(xiàn)實(shí)例,它會(huì)響應(yīng)“get”和“set”屬性值消息。屬性本身保存在叫做attributes的局部字典中。

就像我們?cè)谶@一章的前面看到的那樣,字典本身是抽象數(shù)據(jù)類型。我們使用列表來實(shí)現(xiàn)字典,我們使用偶對(duì)來實(shí)現(xiàn)列表,并且我們使用函數(shù)來實(shí)現(xiàn)偶對(duì)。就像我們以字典實(shí)現(xiàn)對(duì)象系統(tǒng)那樣,要注意我們能夠僅僅使用函數(shù)來實(shí)現(xiàn)對(duì)象。

為了開始我們的實(shí)現(xiàn),我們假設(shè)我們擁有一個(gè)類實(shí)現(xiàn),它可以查找任何不是實(shí)例部分的名稱。我們將類作為參數(shù)cls傳遞給make_instance

>>> def make_instance(cls):
        """Return a new object instance, which is a dispatch dictionary."""
        def get_value(name):
            if name in attributes:
                return attributes[name]
            else:
                value = cls["get"](name)
                return bind_method(value, instance)
        def set_value(name, value):
            attributes[name] = value
        attributes = {}
        instance = {"get": get_value, "set": set_value}
        return instance

instance是分發(fā)字典,它響應(yīng)消息getsetset消息對(duì)應(yīng) Python 對(duì)象系統(tǒng)的屬性賦值:所有賦值的屬性都直接儲(chǔ)存在對(duì)象的局部屬性字典中。在get中,如果name在局部attributes字典中不存在,那么它會(huì)在類中尋找。如果cls返回的value為函數(shù),它必須綁定到實(shí)例上。

綁定方法值。make_instance中的get_value 使用get尋找類中的具名屬性,之后調(diào)用bind_method。方法的綁定只在函數(shù)值上調(diào)用,并且它會(huì)通過將實(shí)例插入為第一個(gè)參數(shù),從函數(shù)值創(chuàng)建綁定方法的值。

>>> def bind_method(value, instance):
        """Return a bound method if value is callable, or value otherwise."""
        if callable(value):
            def method(*args):
                return value(instance, *args)
            return method
        else:
            return value

當(dāng)方法被調(diào)用時(shí),第一個(gè)參數(shù)self通過這個(gè)定義綁定到了instance的值上。

2.6.2 類

類也是對(duì)象,在 Python 對(duì)象系統(tǒng)和我們這里實(shí)現(xiàn)的系統(tǒng)中都是如此。為了簡化,我們假設(shè)類自己并沒有類(在 Python 中,類本身也有類,幾乎所有類都共享相同的類,叫做type)。類可以接受getset消息,以及new消息。

>>> def make_class(attributes, base_class=None):
        """Return a new class, which is a dispatch dictionary."""
        def get_value(name):
            if name in attributes:
                return attributes[name]
            elif base_class is not None:
                return base_class["get"](name)
        def set_value(name, value):
            attributes[name] = value
        def new(*args):
            return init_instance(cls, *args)
        cls = {"get": get_value, "set": set_value, "new": new}
        return cls

不像實(shí)例那樣,類的get函數(shù)在屬性未找到的時(shí)候并不查詢它的類,而是查詢它的base_class。類并不需要方法綁定。

實(shí)例化。make_class 中的new函數(shù)調(diào)用了init_instance,它首先創(chuàng)建新的實(shí)例,之后調(diào)用叫做__init__的方法。

>>> def init_instance(cls, *args):
        """Return a new object with type cls, initialized with args."""
        instance = make_instance(cls)
        init = cls["get"]("__init__")
        if init:
            init(instance, *args)
        return instance

最后這個(gè)函數(shù)完成了我們的對(duì)象系統(tǒng)。我們現(xiàn)在擁有了實(shí)例,它的set是局部的,但是get會(huì)回溯到它們的類中。實(shí)例在它的類中查找名稱之后,它會(huì)將自己綁定到函數(shù)值上來創(chuàng)建方法。最后類可以創(chuàng)建新的(new)實(shí)例,并且在實(shí)例創(chuàng)建之后立即調(diào)用它們的__init__構(gòu)造器。

在對(duì)象系統(tǒng)中,用戶僅僅可以調(diào)用create_class,所有其他功能通過消息傳遞來使用。與之相似,Python 的對(duì)象系統(tǒng)由class語句來調(diào)用,它的所有其他功能都通過點(diǎn)表達(dá)式和對(duì)類的調(diào)用來使用。

2.6.3 使用所實(shí)現(xiàn)的對(duì)象

我們現(xiàn)在回到上一節(jié)銀行賬戶的例子。使用我們實(shí)現(xiàn)的對(duì)象系統(tǒng),我們就可以創(chuàng)建Account類,CheckingAccount子類和它們的實(shí)例。

Account類通過create_account_class 函數(shù)創(chuàng)建,它擁有類似于 Python class語句的結(jié)構(gòu),但是以make_class的調(diào)用結(jié)尾。

>>> def make_account_class():
        """Return the Account class, which has deposit and withdraw methods."""
        def __init__(self, account_holder):
            self["set"]("holder", account_holder)
            self["set"]("balance", 0)
        def deposit(self, amount):
            """Increase the account balance by amount and return the new balance."""
            new_balance = self["get"]("balance") + amount
            self["set"]("balance", new_balance)
            return self["get"]("balance")
        def withdraw(self, amount):
            """Decrease the account balance by amount and return the new balance."""
            balance = self["get"]("balance")
            if amount > balance:
                return "Insufficient funds"
            self["set"]("balance", balance - amount)
            return self["get"]("balance")
        return make_class({"__init__": __init__,
                           "deposit":  deposit,
                           "withdraw": withdraw,
                           "interest": 0.02})

在這個(gè)函數(shù)中,屬性名稱在最后設(shè)置。不像 Python 的class語句,它強(qiáng)制內(nèi)部函數(shù)和屬性名稱之間的一致性。這里我們必須手動(dòng)指定屬性名稱和值的對(duì)應(yīng)關(guān)系。

Account類最終由賦值來實(shí)例化。

>>> Account = make_account_class()

之后,賬戶實(shí)例通過new消息來創(chuàng)建,它需要名稱來處理新創(chuàng)建的賬戶。

>>> jim_acct = Account["new"]("Jim")

之后,get消息傳遞給jim_acct ,來獲取屬性和方法。方法可以調(diào)用來更新賬戶余額。

>>> jim_acct["get"]("holder")
"Jim"
>>> jim_acct["get"]("interest")
0.02
>>> jim_acct["get"]("deposit")(20)
20
>>> jim_acct["get"]("withdraw")(5)
15

就像使用 Python 對(duì)象系統(tǒng)那樣,設(shè)置實(shí)例的屬性并不會(huì)修改類的對(duì)應(yīng)屬性:

>>> jim_acct["set"]("interest", 0.04)
>>> Account["get"]("interest")
0.02

繼承。我們可以創(chuàng)建CheckingAccount子類,通過覆蓋類屬性的子集。在這里,我們修改withdraw方法來收取費(fèi)用,并且降低了利率。

>>> def make_checking_account_class():
        """Return the CheckingAccount class, which imposes a $1 withdrawal fee."""
        def withdraw(self, amount):
            return Account["get"]("withdraw")(self, amount + 1)
        return make_class({"withdraw": withdraw, "interest": 0.01}, Account)

在這個(gè)實(shí)現(xiàn)中,我們?cè)谧宇惖?b>withdraw 中調(diào)用了基類Accountwithdraw函數(shù),就像在 Python 內(nèi)建對(duì)象系統(tǒng)那樣。我們可以創(chuàng)建子類本身和它的實(shí)例,就像之前那樣:

>>> CheckingAccount = make_checking_account_class()
>>> jack_acct = CheckingAccount["new"]("Jack")

它們的行為相似,構(gòu)造函數(shù)也一樣。每筆取款都會(huì)在特殊的withdraw函數(shù)中收費(fèi) $1,并且interest也擁有新的較低值。

>>> jack_acct["get"]("interest")
0.01
>>> jack_acct["get"]("deposit")(20)
20
>>> jack_acct["get"]("withdraw")(5)
14

我們的構(gòu)建在字典上的對(duì)象系統(tǒng)十分類似于 Python 內(nèi)建對(duì)象系統(tǒng)的實(shí)現(xiàn)。Python 中,任何用戶定義類的實(shí)例,都有個(gè)特殊的__dict__屬性,將對(duì)象的局部實(shí)例屬性儲(chǔ)存在字典中,就像我們的attributes字典那樣。Python 的區(qū)別在于,它區(qū)分特定的特殊方法,這些方法和內(nèi)建函數(shù)交互來確保那些函數(shù)能正常處理許多不同類型的參數(shù)。操作不同類型參數(shù)的函數(shù)是下一節(jié)的主題。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/38137.html

相關(guān)文章

  • SICP Python 描述 2.5 面向對(duì)象編程

    摘要:類似消息傳遞中的分發(fā)字典,對(duì)象響應(yīng)行為請(qǐng)求。消息傳遞和點(diǎn)表達(dá)式方法定義在類中,而實(shí)例屬性通常在構(gòu)造器中賦值,二者都是面向?qū)ο缶幊痰幕驹亍J褂脦в袃?nèi)建對(duì)象系統(tǒng)語言的優(yōu)點(diǎn)是,消息傳遞能夠和其它語言特性,例如賦值語句無縫對(duì)接。 2.5 面向?qū)ο缶幊? 來源:2.5 Object-Oriented Programming 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 面向?qū)ο缶幊?..

    starsfun 評(píng)論0 收藏0
  • SICP Python 描述 第二章 使用對(duì)象構(gòu)建抽象 2.1 引言

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

    phoenixsky 評(píng)論0 收藏0
  • SICP Python 描述 第三章 計(jì)算機(jī)程序的構(gòu)造和解釋 3.1 引言

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

    v1 評(píng)論0 收藏0
  • SICP Python 描述 3.4 異常

    摘要:的最常見的作用是構(gòu)造異常實(shí)例并拋出它。子句組只在執(zhí)行過程中的異常產(chǎn)生時(shí)執(zhí)行。每個(gè)子句指定了需要處理的異常的特定類。將強(qiáng)制轉(zhuǎn)為字符串會(huì)得到由返回的人類可讀的字符串。 3.4 異常 來源:3.4 Exceptions 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 程序員必須總是留意程序中可能出現(xiàn)的錯(cuò)誤。例子數(shù)不勝數(shù):一個(gè)函數(shù)可能不會(huì)收到它預(yù)期的信息,必需的資源可能會(huì)丟失,或者網(wǎng)...

    pkhope 評(píng)論0 收藏0
  • SICP Python描述 1.1 引言

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

    xumenger 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<