不可变类型与可变类型

2024-04-18 22:31:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我搞不清什么是不可变类型。我知道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方法,它返回一个字典。带有__new__SortedKeyDict将其标记为错误。我试着用__new__将整数传递给RoundFloat类,它没有标记错误。


Tags: 方法self类型newreturnexampledefval
3条回答

通用不可变类型:

  1. 数字:int()float()complex()
  2. 不可变序列:str()tuple()frozenset()bytes()

常见的可变类型(几乎所有其他类型):

  1. 可变序列:list()bytearray()
  2. 设置类型:set()
  3. 映射类型:dict()
  4. 类,类实例
  5. 等等

快速测试类型是否可变的一个技巧是使用id()内置函数。

例如,在整数上使用

>>> i = 1
>>> id(i)
***704
>>> i += 1
>>> i
2
>>> id(i)
***736 (different from ***704)

在列表中使用

>>> a = [1]
>>> id(a)
***416
>>> a.append(2)
>>> a
[1, 2]
>>> id(a)
***416 (same with the above id)

您必须理解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

要阅读有关Python数据模型的更多信息,可以查看Python语言参考:

什么?浮动是不可变的?但我不能

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]

相关问题 更多 >