不可变与可变类型有什么区别?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (36)

我很困惑什么是不可变的类型。我知道这个float对象被认为是不可变的,我的书中有这样的例子:

class RoundFloat(float):
    def __new__(cls, val):
        return float.__new__(cls, round(val, 2))

这是否被认为是不可变的,因为类结构/层次?,意味着float在类的顶部并且是它自己的方法调用。类似于这种类型的例子(即使我的书说dict是可变的):

class SortedKeyDict(dict):
    def __new__(cls, val):
        return dict.__new__(cls, val.clear())

尽管类中有些可变的方法,例如:

class SortedKeyDict_a(dict):
    def example(self):
        return self.keys()

另外,最后class(SortedKeyDict_a),如果我将这种类型的集合传递给它:

d = (('zheng-cai', 67), ('hui-jun', 68),('xin-yi', 2))

不调用该example方法,它将返回一个字典。在SortedKeyDict__new__其标记为错误。我尝试将整数传递给RoundFloat类,__new__它标记没有错误。

提问于
用户回答回答于

你必须了解Python将其所有数据表示为对象。一些像列表和字典这样的对象是可变的,这意味着你可以改变它们的内容而不改变它们的身份。像整数,浮点数,字符串和元组等其他对象是无法更改的对象。理解这一点的一种简单方法是,如果你查看对象ID。

在下面你看到一个不可变的字符串。您无法更改其内容。TypeError如果您尝试更改它,它会提高。另外,如果我们分配新内容,则会创建一个新对象而不是被修改的内容。

>>> s = "abc"
>>>id(s)
4702124
>>> s[0] 
'a'
>>> s[0] = "o"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>> s = "xyz"
>>>id(s)
4800100
>>> s += "uvw"
>>>id(s)
4800500

你可以用列表来做到这一点,它不会改变对象的身份

>>> i = [1,2,3]
>>>id(i)
2146718700
>>> i[0] 
1
>>> i[0] = 7
>>> id(i)
2146718700
用户回答回答于

但我做不到

x = 5.0
x += 7.0
print x # 12.0

那不是“mut”x吗?

那么你认为字符串是不可改变的吗?但你可以做同样的事情。

s = 'foo'
s += 'bar'
print s # foobar

变量的值会发生变化,但它会通过更改变量引用的内容而发生变化。可变类型可以改变这种方式,它也可以 “就地”改变。

这是区别。

x = something # immutable type
print x
func(x)
print x # prints the same thing

x = something # mutable type
print x
func(x)
print x # might print something different

x = something # immutable type
y = x
print x
# some statement that operates on y
print x # prints the same thing

x = something # mutable type
y = x
print x
# some statement that operates on y
print x # might print something different

具体的例子

x = 'foo'
y = x
print x # foo
y += 'bar'
print x # foo

x = [1, 2, 3]
y = x
print x # [1, 2, 3]
y += [3, 2, 1]
print x # [1, 2, 3, 3, 2, 1]

def func(val):
    val += 'bar'

x = 'foo'
print x # foo
func(x)
print x # foo

def func(val):
    val += [3, 2, 1]

x = [1, 2, 3]
print x # [1, 2, 3]
func(x)
print x # [1, 2, 3, 3, 2, 1]

扫码关注云+社区