1. python中的变量是什么?
python和java的变量本质不一样, python的变量实质上是一个指针 类似便利贴
便利贴过程:
a = 1
# 1.先在内存中生成好了1
# 2.把a贴在1上面
代码举例:
>>> a = [1, 2, 3]
>>> b = a
>>> print(id(a), id(b))
4329385544 4329385544
>>> print(a is b)
True
2. ==和is的区别
以代码说明:
>>> a = [1, 2, 3, 4]
>>> b = [1, 2, 3, 4]
>>> print(a == b) # ==其实是调用了__eq__魔法函数
True
>>> print(id(a), id(b))
4400893512 4400893640
>>> print(a is b) # is判断的是 内存是不是同一地址
False
# 证明 类 在python中是唯一的
>>> class People:
>>> pass
>>> person = People()
>>> if type(person) is People:
>>> print('type(person) is People')
type(person) is People
3. del语句和垃圾回收
python中的垃圾回收是 采用引用技术,当引用计数器为0时,才会删除
>>> a = 1 # 引用计数器为1
>>> b = a # 引用计数器加1
>>> del a # 引用计数器减1
>>> print(b) # del 了a, b依然存在
1
>>> print(a)
Traceback (most recent call last):
File "6_what_is_var/3_delete.py", line 7, in <module>
print(a)
NameError: name 'a' is not defined
通魔法函数__del__ 可以自定义 类在被回收时,需要做什么
>>> class A:
>>> def __del__(self):
>>> print('__del__ here')
>>> a = A()
>>> del(a) # 或 del a
__del__ here
3. 一类经典的list参数错误
代码举例1:
>>> def add(a, b):
>>> a += b
>>> return a
>>> if __name__ == '__main__':
>>> a = 1
>>> b = 2
>>> c = add(a, b)
>>> print(c)
3
>>> print(a, b)
1 2
>>> a = [1, 2]
>>> b = [3, 4]
>>> c = add(a, b)
>>> print(c)
[1, 2, 3, 4]
>>> print(a, b) # 传入的参数类型是list时, a的值也改变了
[1, 2, 3, 4] [3, 4]
>>> a = (1, 2)
>>> b = (3, 4)
>>> c = add(a, b)
>>> print(c)
(1, 2, 3, 4)
>>> print(a, b)
(1, 2) (3, 4)
代码举例2:
>>> class Company:
>>> def __init__(self, name, staffs=[]):
>>> self.name = name
>>> self.staffs = staffs
>>> def add(self, staff_name):
>>> self.staffs.append(staff_name)
>>> def remove(self, staff_name):
>>> self.staffs.remove(staff_name)
>>> if __name__ == '__main__':
>>> com1 = Company('com1',['cannon1', 'cannon2'])
>>> com1.add('cannon3')
>>> com1.remove('cannon1')
>>> print(com1.staffs)
['cannon2', 'cannon3']
>>> com2 = Company('com2')
>>> com2.add('cannon4')
>>> com3 = Company('com3')
>>> com3.add('cannon5')
>>> print(com2.staffs) # com2 com3 使用了默认的staffs 得到了一样的staffs值
['cannon4', 'cannon5']
>>> print(com3.staffs)
['cannon4', 'cannon5']
>>> print(com2.staffs is com3.staffs) # com2 和 com3 没传入staffs, 默认[]。com2 com3共用了
True
# 我们可以直接用类 名获取默认的[]
>>> print(Company.__init__.__defaults__)
(['cannon4', 'cannon5'],)
结论:
-
为避免以上出现的错误,我应尽量不使用list作为传入参数。即使不得已使用了,也要做好传入参数本身会被改变的准备。