您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Ruby與Python的對象系統(tǒng)有什么區(qū)別”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Ruby與Python的對象系統(tǒng)有什么區(qū)別”吧!
屬性的嚴(yán)格定義不知道去哪里找, 這里暫且用來指對象實(shí)例用來儲存自身狀態(tài)的方式好了。 用途自然是儲存對象的協(xié)作者與數(shù)據(jù)等。 或者干脆說成是: per-instance 的東西都叫屬性1。
一般來說, 對象的內(nèi)部狀態(tài)輕易不向外暴露, 讀寫操作主要由對象的方法完成。 這種自己默默修改自身屬性的存取方式我們暫時(shí)稱作內(nèi)部訪問。
Ruby 中為每個(gè)對象提供了單獨(dú)的命名空間來存放屬性, 語法上 @foo
是讀取,@foo = 'bar'
是寫入。 而且讀寫語義無法通過元編程來干擾。 也不與常量查找、方法調(diào)用、局部變量存取等尋址方式相沖突。
在 Python 中這種命名空間似乎也是存在的, 而且乍一看可以通過 __dict__
字典來訪問2。 但由于打字太多, 實(shí)際恐怕很少有人積極使用, 更多地還是直接用外部訪問的方法。 往下看。
Ruby 默認(rèn)禁止外部直接訪問對象屬性3, 需要我們顯式地在類定義中使用attr
系列方法 來顯式定義供外部使用的存取方法。
Python 這邊就容易得多, 自定義的 New Style Class 默認(rèn)有 __dict__
屬性4, 讀寫全開, 可以直接用 foo.bar
,foo.bar = 'baz'
語法存取, 內(nèi)部存取時(shí)多半也用這種語法。
這里我不想談及定義了 __slots__
的情況, 因?yàn)榭次臋n里面一長串需要當(dāng)心的 notes 可以猜測沒什么人愿意用。 稍微 Google 一下的結(jié)果也基本證實(shí)如此。
兩種語言都支持在語法上依然寫出常規(guī)的屬性取值/賦值, 而背后執(zhí)行任意的代碼。 常用的場景包括延遲求值, 計(jì)算屬性(Calculated Attribute), 只讀屬性等。
在 Ruby 里由于語法糖實(shí)在太甜, 調(diào)用方法時(shí)可以省略掉括號, 能夠不傳參數(shù)調(diào)用的方法就是 getter, 寫起來像 foo.bar
。 以 =
結(jié)尾的一元方法就是 setter, 通過 foo.bar = 'baz'
就會調(diào)用到。 前面提到的 attr 系列方法 也只是按照這個(gè)接口來定義方法, 并非特殊的語言關(guān)鍵字。
至于 Python, 只需 getter 時(shí)還好說, 直接用 @property
裝飾器就好。 但需要允許外部只讀訪問屬性時(shí)就有些麻煩。 讀寫控制要由 property descriptor 來實(shí)現(xiàn), 為了自定義一個(gè)只讀 descriptor 寫起來像這樣:
EDIT: 明顯下面的代碼是不對的, 當(dāng)時(shí)我在想什么。 還好真實(shí)世界中一般都用下劃線方案而不是用這種方案來滿足語義純化論者。
class Foo(object): bar = property() @bar.setter def bar(self, value): raise AttributeErrorFoo().bar = 'shit' # => 拋 AttributeError 異常
這樣在內(nèi)部訪問中要寫入屬性時(shí)就要被迫改用這種傷鍵盤的寫法:self.__dict__['bar'] = 'blah'
。 所以現(xiàn)實(shí)生活中人們往往用下劃線開頭表達(dá)私有屬性, 然后定義一個(gè)去掉開頭下劃線的 getter 來提供只讀訪問了事。
到這里已經(jīng)可以總結(jié)出我偏好 Ruby 的一點(diǎn)原因:
對屬性的內(nèi)部與外部存取做出明確區(qū)分, 默認(rèn)不提供外部直接存取。 且兩種存取方式的語法都不難寫。 鼓勵(lì)開發(fā)者在設(shè)計(jì)時(shí)考慮好封裝問題。 而 Python 慣用的方式是下劃線標(biāo)識私有屬性, 難免會增加代碼量。
接下來如果再寫下去要一并引入很多對象模型的重點(diǎn)問題, 恐怕就要被標(biāo)記 TL;DR 了。 所以先到這吧。
未來談及方法解析的時(shí)候會引入 per-instance 的方法定義, 從而毀掉這個(gè)不嚴(yán)格的描述。
但是你沒法通過自定義 __dict__
返回值來擾亂屬性專有字典。 是的, 在這兩種語言元編程的能力下, 可以做出很多出格的事情來。 本文只能在假設(shè)開發(fā)者不會積極地亂來的基調(diào)下展開討論。
當(dāng)然你可以用 instance_variable_{get,set,s}
等方法來訪問。 避而不談的理由見另一個(gè)腳注。
object
類自己卻沒有定義 __dict__
, 其實(shí)例也沒有。 所以盡管這樣一個(gè)空的 New Style Class class Foo(object): pass
是 object 的直接子類, 兩個(gè)類的實(shí)例的行為卻大不相同。
到此,相信大家對“Ruby與Python的對象系統(tǒng)有什么區(qū)別”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。