在 Python 中一切都可以看作为对象。每个对象都有各自的 id, type 和 value。
id: 当一个对象被创建后,它的 id 就不会在改变,这里的 id 其实就是对象在内存中的地址,可以使用 id() 去查看对象在内存中地址。
type: 和 id 一样当对象呗创建之后,它的 type 也不能再被改变,type 决定了该对象所能够支持的操作
value: 对象的值
一个对象可变与否就在于 value 值是否支持改变。
不可变对象
常见的不可变对象(immutable objects):
Number: int, float, complex
string
t
在Python编程语言中,对象是其核心概念之一。对象具有三个关键属性:id、type和value。理解这些属性有助于我们区分可变对象和不可变对象,这是Python编程中非常重要的概念。
1. **id**: 对象的id表示其在内存中的唯一标识,一旦对象创建,它的id就不会改变。你可以使用内置的`id()`函数来获取对象的id。这通常代表了对象在内存中的地址。
2. **type**: 对象的type决定了它可以进行哪些操作。例如,整数(int)、浮点数(float)、复数(complex)是不可变的数字类型,字符串(str)也是不可变的。一旦创建,它们的类型无法更改。
3. **value**: 对象的value决定了它是否可变。如果对象的value不能改变,那么该对象被称为不可变对象;反之,如果value可以改变,则为可变对象。
**不可变对象**:
不可变对象包括整型(int)、浮点型(float)、复数型(complex)、字符串(str)和元组(tuple)。不可变对象的特点是,一旦创建,它们的值就不能被修改。尝试修改不可变对象会创建一个新的对象,而不是改变原有对象。例如,当你尝试改变一个整数变量的值,实际上是在创建一个新的整数对象并更新变量的引用。
```python
x = 1
y = x
id(x) == id(y) # True
x = x + 1
id(x) == id(y) # False
```
在这个例子中,x和y最初指向同一个整数对象,但当x的值增加1时,x现在指向了一个新的整数对象。
**可变对象**:
可变对象包括列表(list)、字典(dict)和集合(set)。它们的值可以被修改,不会创建新的对象。例如,列表可以通过索引访问并改变元素的值。
```python
c = [1, 2, 3]
b = c
id(b) == id(c) # True
c[0] = 4
id(c) == id(b) # True
```
在这个例子中,虽然列表c的一个元素被修改,但c和b依然指向同一个列表对象,因为列表是可变的。
**函数参数**:
在函数调用时,不可变对象和可变对象的行为不同。对于不可变对象,函数内部的修改不会影响到原始对象,因为它们不允许直接改变。而对于可变对象,函数内部的修改会影响到原始对象,因为它们是可变的。
```python
def update_list(nums_list):
print(f'2 id:{id(nums_list)}')
nums_list += [10]
print(f'3 id:{id(nums_list)}')
number_list = [5, 6]
print(f'1:{number_list}, id:{id(number_list)}')
update_list(number_list)
print(f'4:{number_list}, id:{id(number_list)}')
```
在这个例子中,尽管`nums_list`在函数内部被修改,但它的id没有变化,因为列表本身是可变的。
```python
def add_num(number):
print(f'2:{id(number)}')
number += 1
print(f'3:{id(number)}')
num = 1
print(f'1:{num}, id:{id(num)}')
add_num(num)
print(f'4:{num}, id:{id(num)}')
```
这个例子展示了对不可变对象(整数)的修改。尽管在函数内部`number`的值看起来改变了,但其实创建了一个新的整数对象,原始的整数对象保持不变。
理解Python中可变对象和不可变对象的概念对于编写高效、无副作用的代码至关重要。在处理函数参数或共享数据时,应根据对象的可变性选择合适的数据结构,以避免意外的副作用。