pickle
使用pickle可以储存各种各样的数据,储存和读取的命令如下:
import pickle
fw = open('dataFile.txt','wb')
pickle.dump(obj, fw)
fw.close()
fw = open('dataFile.txt','rb')
obj = pickle.load(fw)
fw.close()
关键在于,obj中可以包含自己定义的类,例如:
import pickle
import myClass
obj = {'key1': myClass()}
fw = open('dataFile.txt','wb')
pickle.dump(obj, fw)
fw.close()
那么在读取的时候,文件也必须import自己定义的类,如果不import会报错。
路径问题
首先,一定不要使用绝对路径。
其次,在pycharm能运行的文件,到了控制台中不一定,因为很容易就出现中找不到module,但module的路径是没有问题的。这时候就需要考虑,python project是否被加入了os的路径中。可以参考下面两个博客
https://blog.csdn.net/weixin_41357300/article/details/81483846
https://blog.csdn.net/weixin_43483847/article/details/89360505
使用os.path.append将你的project的路径进去。
deep和deepcopy的区别
我们常说的“复制”就是在说“深复制”,就是完全复制一个独立的东西出来。在python中,“a=2”比给“a赋值2”更好的理解是“给2贴上标签a”
>>> a = [1, 2, 3]
>>> b = a
>>> print(b)
[1, 2, 3]
copy和deepcopy的区别在于,对于复杂对象(例如list的元素是list,或者dict的元素是list),copy只能独立复制外边一层变量,而作为元素的list是共享的。而deepcopy则是完全生成一个独立的变量。再来做一个实验:
import copy
a = [[1, 1], [2, 2]]
b = a
a_copy = copy.copy(a)
a_deepcopy = copy.deepcopy(a)
print('--------change the outside list----------')
a[0] = [0, 0]
print('a:', a)
print('b:', b)
print('a_copy:', a_copy)
print('a_deepcopy:', a_deepcopy)
print('--------change the inside list--------')
a[0][0], a[0][1] = 'hello', 'wow'
print('a:', a)
print('b:', b)
print('a_copy:', a_copy)
print('a_deepcopy:', a_deepcopy)
输出是:
--------change the outside list----------
a: [[0, 0], [2, 2]]
b: [[0, 0], [2, 2]]
a_copy: [[1, 1], [2, 2]]
a_deepcopy: [[1, 1], [2, 2]]
--------change the inside list--------
a: [[‘hello’, ‘wow’], [2, 2]]
b: [[‘hello’, ‘wow’], [2, 2]]
a_copy: [[1, 1], [2, 2]]
a_deepcopy: [[1, 1], [2, 2]]
用到copy的场景:认为复杂对象其中的子对象是一个公共的,被大家所共用的,这时则应该使用copy。
@的用法
def funA(fn):
print('aaa')
@funA
def funB():
print('bbbb')
这句话相当于执行了以下操作:
funB = funA(funB())
其中funA没有返回值,所以最终funB是一个Nonetype的None。
1、此时如果在控制台输入“funB”,则会打印aaa,过程是:执行funA,打印了’aaa’,然后没有返回值给了funB,所以funB就是一个None,类型是Nonetype。
所以如果。
2、此时如果在控制台输入“funB()”,由于上面已经分析了funB是None,并不可以调用,所以会报错。
def funA(fn):
print('aaa')
return 2
@funA
def funB():
print('bbbb')
# 此时,funB相当于是2,但仍然不会执行funB中打印'bbb’的语句。
更需要理解一下装饰器的应用场景:
注册表:https://www.cnblogs.com/superhin/p/11454823.html
增添函数的功能:https://blog.csdn.net/weixin_42544006/article/details/93506206
map的用法
map的用法为map(function, iterable),其中function为一个函数,iterable是一个或者多个可迭代的量。python3返回的是一个迭代器。如果想要返回列表,可以使用
a = list(map(fun, A))
sort自定义排序函数
python3中,要想自定义sort的比较函数,需要另外一个包:
from functools import cmp_to_key
nums = ['10', '2']
nums.sort(key=cmp_to_key(lambda x,y: int(str(x) + str(y)) - int(str(y) + str(x))))
sort中定义key为一个函数。
全排列
from itertools import permutations
print(list(permutations([1, 2, 3])))
python整数的表示
python的整数表示没有范围。python中的整数都是以补码形式储存。
接下来讨论对于32位整数操作的事情。
由于python整数表示没有范围,所以如果想要获取一个32位表示的整数x的补码,需要做如下操作,这相当于取了前32位:
x = x & 0xffffffff
但这么做后,其实x的表示方法并不符合python的存储规则。如果想要把x的再变成符合python的规则,需要做~(x & 0xffffffff)操作。结果如下:
x = -1
x1 = x & 0xffffffff
print(hex(x1)) # 0xffffffff
print(x1) # 4294967295
print(~(x1 ^ 0xffffffff)) #-1
看到,第一个print表示确实输出了-1的补码,第二个print表示说明直接输出补码python不认,第三个print表示经过转换python才认。
对于64位,应该就是把0xffffffff换成0xffffffffffffffff。
python的垃圾回收机制
https://blog.csdn.net/xiongchengluo1129/article/details/80462651
主要方法就是引用计数,在如下操作,对一个对象的引用计数加1:
- 对象被创建
- a=14 对象被引用
- b=a 对象被作为参数,传到函数中
- func(a) 对象作为一个元素,存储在容器中 List={a,”a”,”b”,2}
在如下操作,引用计数减1:
- 当该对象的别名被显式销毁时 del a
- 当该对象的引别名被赋予新的对象, a=26
- 一个对象离开它的作用域,例如 func函数执行完毕时,函数里面的局部变量的引用计数器就会减一(但是全局变量不会)
- 将该元素从容器中删除时,或者容器被销毁时。
当引用计数变为0的时候,就对象的内存就会被释放。