python和java中的变量本质不一样,java的变量像盒子,python的变量实质是指针,类似便利贴
a = 1
b = 1
print(a is b) # True
a_list = [1, 2, 3, 4]
b_list = [1, 2, 3, 4]
print(a is b) # False
python内部 有个intern机制,strintfloat这些单个数据,会作为一个完整的对象
但listdict都是会另外生成新对象
print(a_list == b_list) # True,列表中有个魔法函数__eq__判断值是否相等
person = Person()
if type(person) is Person:
print("yes")
python中垃圾回收的算法是采用引用计数
a = 1 # 1这个对象的计数器会加1
b = a # 1这个对象的计数器再加1
del a
del是将计数器减1,同时取消a指针(变量a被删除),但实际上1这个对象还是存在的。C++中的del则不同,会直接将这个1对象删除
a = object()
b = a
del a
print(b) # 会打印
print(a) # 会报错
class A:
# 当python回收对象时,会调用__del__魔法函数
def __del__(self):
pass
1、列表在函数局部空间里使用+=,是会改变列表本身的
def add(a, b):
a += b
# 不同数据传递,a会有不同影响,尤其列表,列表在局部空间里是会被修改的
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) # [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=[]): # 注意,默认的可变对象list,会成为为传递值的对象的公共数据
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传递了list,因此不会与其他对象com2com3共用默认列表
com1 = Company("com1", ["bobby1", "bobby2"])
com1.add("bobby3")
com1.remove("bobby1")
print(com1.staffs) # ["bobby2","bobby3"]
# com2和com3都没有传递list,都使用默认的staffs=[],list本身是可变对象,因此com2和com3会公用默认的staffs=[]
com2 = Company("com2")
com2.add("bobby")
print(com2.staffs) # ["bobby"]
com3 = Company("com3")
com3.add("bobby5")
print(com2.staffs) # ["bobby","bobby5"]
print(com3.staffs) # ["bobby","bobby5"]
print(com2.staffs is com3.staffs) # True
print(com2 is com3) # False
# 获取默认值,这是com2和com3未传递值时的共用默认值
print(Company.__init__.__defaults__)