首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Python使可变对象的行为不可变

Python使可变对象的行为不可变
EN

Stack Overflow用户
提问于 2018-07-14 03:40:57
回答 1查看 177关注 0票数 -5

编辑:我没有改变对象的可变性,只是让变量的行为像它一样。我的脑海中没有具体的实现,但可能会使用它来使元组具有可变项hashable

据我所知,在python中,您可以通过将对象封装在一个列表中,使其行为像C指针一样,从而使不可变对象的行为像可变对象一样--特别是使它们不可哈希,并且您可以编辑对象而不必创建新的对象:

代码语言:javascript
复制
myVar = 5
myVar2 = myVar
#both point to same object 5
myVar += 1
#myVar2 still 5, myVar has new object 6

myVar = [5]
#myVar is no longer immutable
myVar2 = myVar
myVar[0] += 1
#myVar2 is now also 6

这意味着您可以更改变量指向的对象的值,它将影响引用该对象的所有变量

但是,有没有一种相反的方法--让可变对象的行为不可变(并且是可哈希的)?元组不能这样做-如果元组中的值是可变的,那么它是可以改变的,而具有可变对象的元组是不可哈希的。我主要想这样做,这样它就可以像不可变对象一样存储,其中具有相同值的变量都指向相同的对象,而对变量的更改会产生一个新的对象,而不会影响其他变量,或者我必须使用OOP重新实现python name方法吗?

摘要:我想为可变对象提供一个不可变的包装器,与元组不同的是,它不允许编辑项,并且是可哈希的

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-14 03:56:50

Python没有变量。它有名字。所有名称都指向一个对象。

属性使名称指向对象。就是这么简单。你不能让属性隐式地生成一个新对象。

代码语言:javascript
复制
a = x
b = a # means the name "b" also refers to x - regardless if x is mutable or not

所以不,你不能用这种方式使可变对象不可变--如果有人获得了一个可变对象的引用,他们可以改变它,并且所有对同一对象的引用都会受到影响。

仅仅因为一个对象是不可变的,并不会使具有相同值的对象自动变得相同--试试这个:

代码语言:javascript
复制
>>> x = 'foo bar'
>>> y = ' '.join(['foo', 'bar'])
>>> x == y
True
>>> x is y
False
>>> id(x), id(y)
(139789175899936, 139789175899984)

如您所见,它们是两个不同的不可变对象,具有相同的值!两者都单独存在于内存中!

要使它们可以散列是可能的-你必须定义一个__hash__方法,它返回一些唯一的散列,当对象相等时比较相等-事实上,默认情况下所有对象都已经返回id作为散列,所以你只需要包装一个类:

代码语言:javascript
复制
class HashableContainer:
    def __init__(self, obj):
        self._obj = obj

l = [] # mutable, no hash
ic = HashableContainer(l) # mutable, but hashable

d = {}
d[ic] = 'test' # can be used as key

但是有一个警告--如果你生成一个具有相同内容的新HashableContainer,它将被认为是一个不同的对象--因为它将有一个不同的散列(基于它的id)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51331854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档