简体   繁体   English

Python相当于JavaScript的Object.create()

[英]Python equivalent of JavaScript's Object.create()

What would be the Python equivalent of JavaScript's Object.create() functionality? 什么是Python的Object.create()功能的Python等价物?

For example, in JS this is possible: 例如,在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

The closest thing I can think of is using copy : 我能想到的最接近的是使用副本

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

It works, but it seems very wasteful to create a new copy of the reference object each time I want to inherit its properties. 它有效,但每次我想继承其属性时,创建引用对象的新副本似乎非常浪费。

Also I'm working with simple objects of the type seen above... not class instances. 我也在使用上面所见类型的简单对象...而不是类实例。

The dictionary class dict accepts another dictionary in its constructor. 字典类dict在其构造函数中接受另一个字典。

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

This is a shallow copy, which is fine when you're using immutable objects as values. 这是一个浅拷贝,当您将不可变对象用作值时,这很好。 (Keys must always be immutable types.) If you are using mutable containers such as other dictionaries (or lists, or various other types) as values, you should use copy.deepcopy() . (键必须始终是不可变类型。)如果您使用可变容器(如其他字典(或列表或其他各种类型))作为值,则应使用copy.deepcopy()

It's important to note that in Python, items in a container (like a dict ) and attributes on an object are different things entirely, accessed in different ways, and neither is exactly like a property in JavaScript. 重要的是要注意,在Python中,容器中的项(如dict )和对象上的属性完全不同,以不同的方式访问,并且都不像JavaScript中的属性。 What you are actually trying to do is better accomplished by classes in Python: 您实际上要做的是通过Python中的类更好地完成:

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

s = Thing()
t = Thing()

In this case, s.pots accesses the value stored on the Thing class until you actually assign s.pots , at which point the instance's value of that attribute shadows the value stored on the class. 在这种情况下, s.pots访问存储在Thing类中的值,直到您实际分配s.pots ,此时该属性的实例值会s.pots存储在类中的值。 So space is used on the instance only for attributes that have actually been assigned. 因此,实例上仅对实际已分配的属性使用空间。

You can also define __slots__ on the class to allow only attributes of specific names to be assigned; 您还可以在类上定义__slots__ ,以仅允许分配特定名称的属性; this can reduce the memory overhead of instances, which is handy if you will be creating a lot of them. 这可以减少实例的内存开销,如果你要创建很多实例,这很方便。

The Python way of accessing attributes using a variable (or expression) rather than dot notation is the getattr() function. 使用变量(或表达式)而不是点表示法访问属性的Python方法是getattr()函数。 It is possible to create an object that can access the same data using either . 可以创建一个可以使用其中任何一个访问相同数据的对象. or [] , but it's trickier than you might expect to get it to work exactly like it does in JavaScript. []但它比你想象得到像它在JavaScript中所做的只是工作完全棘手。

When you are using classes, the closest equivalent to your example (given an s , create a t with s 's own attributes) is something like this: 当您使用类,最接近相当于你的例子(给出一个s ,创建一个ts自己的属性)是这样的:

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

You could provide a method to do this: 您可以提供一种方法来执行此操作:

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

Then derive Thing from Cloneable rather than object and you can do: 然后从Cloneable而不是object派生Thing ,你可以这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM