2017-02-11 172 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。 –