【发布时间】:2016-12-02 10:44:52
【问题描述】:
我想更好地理解 Python 3.x 数据模型。但是我没有找到关于 Python 对象行为的完整而准确的解释。
我正在寻找参考资料,如果我在下面展示的每个案例都可以链接到 Python API 参考资料或 PEP 或其他任何有价值的东西,那就太好了。进一步感谢您的明智建议...
假设我们有一些复杂的 Python 结构用于测试目的:
d1 = {
'id': 5432
,'name': 'jlandercy'
,'pets': {
'andy': {
'type': 'cat'
,'age': 3.5
}
,'ray': {
'type': 'dog'
,'age': 6.5
}
}
,'type': str
,'complex': (5432, 6.5, 'cat', str)
,'list': ['milk', 'chocolate', 'butter']
}
1) 不可变原子对象是单例
无论我如何创建一个新整数:
n1 = 5432
n2 = int(5432)
n3 = copy.copy(n1)
n4 = copy.deepcopy(n1)
不会创建此编号的新副本,而是指向与d1['id'] 相同的对象。更简洁
d1['id'] is n1
...
它们都有相同的id,我无法创建一个值为 5432 的 int 的新实例,因此它是一个单例。
2) 不可变和可迭代对象可能是单例...
先前的观察也适用于str,它们是不可变的和可迭代的。以下所有变量:
s1 = 'jlandercy'
s2 = str('jlandercy')
s3 = copy.copy(s1)
s4 = copy.deepcopy(s1)
指向最初创建的副本d1['name']。字符串也是单例。
...但不完全是...
Tuple 也是 immutable 和 iterable,但它们的行为不像字符串。众所周知,神奇的空元组是一个单例:
() is ()
但其他元组不是。
t1 = (5432, 6.5, 'cat', str)
...相反,它们的哈希值相等
他们没有相同的id:
id(d1['complex']) != id(t1)
但这两个结构中的所有项目都是原子的,因此它们指向相同的实例。重要的一点是,hash 的两个结构都一样:
hash(d1['complex']) == hash(t1)
所以它们可以用作字典键。对于嵌套元组也是如此:
t2 = (1, (2, 3))
t3 = (1, (2, 3))
他们确实有相同的hash。
3) 通过双重解引用传递字典作为它的浅拷贝
让我们定义以下函数:
def f1(**kwargs):
kwargs['id'] = 1111
kwargs['pets']['andy'] = None
将通过双重取消引用(** 运算符)接收我们的试用字典的一级成员将被复制,但最深的成员将通过引用传递。
这个简单程序的输出,说明它:
print(d1)
f1(**d1)
print(d1)
返回:
{'complex': (5432, 6.5, 'cat', <class 'str'>),
'id': 5432,
'list': ['milk', 'chocolate', 'butter'],
'name': 'jlandercy',
'pets': {'andy': {'age': 3.5, 'type': 'cat'},
'ray': {'age': 6.5, 'type': 'dog'}},
'type': <class 'str'>}
{'complex': (5432, 6.5, 'cat', <class 'str'>),
'id': 5432,
'list': ['milk', 'chocolate', 'butter'],
'name': 'jlandercy',
'pets': {'andy': None, 'ray': {'age': 6.5, 'type': 'dog'}},
'type': <class 'str'>}
字典d1 已被函数f1 修改,但不是完全修改。成员id'被保留,因为我们在做一个副本,但是成员pets也是一个字典,浅拷贝没有复制它,所以它已经被修改了。
此行为类似于 dict 对象的 copy.copy 行为。我们需要copy.deepcopy 来获得对象的递归和完整副本。
我的要求是:
-
我的观察得到了正确的解释吗?
不可变原子对象是单例
Immutable 和 Iterable 对象可能是单例,但不完全是,它们的哈希值相等
通过双重解引用传递字典作为它的浅拷贝
- 这些行为是否有据可查?
- 对于每种情况,都说明了正确的属性和行为。
【问题讨论】:
标签: python python-3.x object reference