2017-02-11 108 views
1

JavaScript的Object.create()功能的Python等價物是什麼?等效於Python的Object.create()

例如,在JS這是可能的:

var s = { 'pots': 5, 'cups': 2 }; 
var t = Object.create(s); 
console.log(t['pots']);    // 5 

t['pots'] = 9000; 
console.log(t['pots']);    // 9000 
console.log(t['__proto__']['pots']); // 5, unchanged 

s['pots'] = 33; 
console.log(t['pots']);    // 9000, unchanged 
console.log(t['__proto__']['pots']); // 33 

我能想到的最接近的是使用copy

s = { 'pots': 5, 'cups': 2 } 
t = copy.copy(s) 

它的工作原理,但它似乎很浪費,以創建一個新的每次我想要繼承它的屬性時引用對象的副本。

另外我正在使用上面看到的類型的簡單對象...不是類實例。

+0

「簡單對象」和類實例之間沒有區別 - 所有對象的行爲方式都是相同的。 Python使用基於類的繼承而不是基於原型的繼承。 –

回答

3

字典類dict在其構造函數中接受另一個字典。

s = { 'pots': 5, 'cups': 2 } 
t = dict(s) 

這是一個淺拷貝,當你使用不可變對象作爲值時,它是很好的。 (鍵必須始終爲不可變類型。)如果使用可變容器(如其他字典(或列表或其他類型)作爲值),則應使用copy.deepcopy()

重要的是要注意,在Python中,容器中的項目(如dict)和對象上的屬性完全不同,它們以不同的方式訪問,並且都不完全像JavaScript中的屬性。什麼你實際上是試圖做在Python是更好地完成通過類:

class Thing(object): 
    pots = 5 
    cups = 2 

s = Thing() 
t = Thing() 

在這種情況下,s.pots訪問存儲在Thing類的值,直到你實際分配s.pots,此時該屬性的實例的值陰影存儲在類中的值。因此,實例上的空間僅用於實際分配的屬性。

您也可以在該類上定義__slots__以僅允許分配特定名稱的屬性;這可以減少實例的內存開銷,如果您要創建大量實例,這很方便。

使用變量(或表達式)而不是點符號訪問屬性的Python方法是getattr()函數。可以使用.[]創建一個可以訪問相同數據的對象,但它比您期望的更復雜,它可以像0128在JavaScript中一樣工作,正好是

當您使用類,最接近相當於你的例子(給出一個s,創建一個ts自己的屬性)是這樣的:

t = type(s)() 
t.__dict__.update(s.__dict__) 

你可以提供一個方法來做這樣的:

class Cloneable(object): 
    def clone(self): 
     inst = type(self)() 
     inst.__dict__.update(self.__dict__) 
     return inst 

然後從Cloneable而不是object得到Thing,你可以這樣做:

s = Thing() 
t = s.clone() 
+0

呵呵。我喜歡這個觀點。 Upvoted。 –