美文网首页
【Note】搬砖路上遇到的坑

【Note】搬砖路上遇到的坑

作者: 火禾子_ | 来源:发表于2019-03-10 11:41 被阅读0次

1 关于内存管理的那些事(is VS ==)

首先,变量类型分为一下两个大类。

可变类型,值可以改变:

  • 列表 list
  • 字典 dict

不可变类型,值不可以改变:

  • 数值类型 int, long, float
  • 布尔类型 bool
  • 字符串 str
  • 元组 tuple

1-1 怎么体现是可变/不可变的类型呢?

背景:在python中通过 = 复制的变量,都是同时即把变量的值,也把变量在内存中的地址复制也过去了(这样的说法不是绝对正确的,在命令行中不是通用的)。即 = 复制过的变量不仅内存地址一样,变量的值也一样。但是需要注意的是:对于不可变类型(如 int)的变量,如果要更改变量的值,则会创建一个新值,并且给这个新值分配一个新的内存地址,然后把变量指向这个新值的内存地址上,而旧值如果没有被引用就等待垃圾回收。如果是可变类型变量,若修改变量的值,则可以直接修改变量的值,变量的引用地址不会变。

不可变类型 注意 python 中创建两个内容一样的变量时(变量名不一样),一般都会在内存中分配两个内存地址分别给这两个变量。即两个变量的内容虽然一样,但是变量的引用地址不一样。所以两个变量使用 == 比较成立,但是使用 is 比较不成立。这里有两个特例,小整数和 str,稍后会详细介绍。

以 int 类型为例,当创建完对象后,内存就不可变。所以当要改变值的时候,只能另辟一块内存来存储新计算出来的值。而之前开辟的内存里存储的值不变。

下面代码中 b 的值和地址都没变,也没有随着 a 的值改变而改变,就是这个道理。b 仍指向原来的内存,而 a 指向新的内存。

a = 10
b = a
print(a, id(a), b, id(b))
a += 2
print(a, id(a), b, id(b))

输出:
10 4310353248 10 4310353248
12 4310353312 10 4310353248

可变类型 以列表为代表,内存是可扩充的。因此,当 list1 改变时,是在本来的内存上扩充的,list1 和 list2 仍指向原来的内存。

list1 = ['a']
list2 = list1
print(list1, id(list1), list2, id(list2))
list1.append('b')
print(list1, id(list1), list2, id(list2))

输出:
['a'] 4342566728 ['a'] 4342566728
['a', 'b'] 4342566728 ['a', 'b'] 4342566728

1-2 体现在 is 和 == 上,是什么情况呢?

  • == 判断 内容/值是否相同
  • is 判断内容/值是否相同 && 内存地址是否相同

所以相应的,对于可变类型,因为赋值时给的是引用,内存大小可以随着值的变化而自动扩容,所以无论是 == 还是 is 都是 True。对于不可变类型,在 PyCharm 中,只要是 == 判定为 True 的,一般 is 也会判定为 True。为什么有个 PyCharm 的前提呢?那就接着往下看吧。

1-3 特例一:使用 is 时注意 python 对于小整数使用对象池存储问题

注意,因为 python 对小整数在内存中直接创建了一份,不会回收。因此所有创建的小整数变量直接从对象池中引用即可。
但是注意 python 仅仅对比较小的整数对象进行缓存(范围 [-5, 256] )缓存起来,而并非是所有整数对象。也就说只有在这个 [-5,256] 范围内创建的变量值使用 is比较时候才会成立。

>>> a = 10
>>> b = 10
>>> c is d
True
>>> c = 1000
>>> d = 1000
>>> c is d
False
>>> e ,d ,f ,g = -5 ,-5 ,-6 ,-6
>>> e is d
True
>>> f is g  #超过-5的范围不成立
False

注意:上面对于 python 小整数对象池的使用仅仅是在命令行中执行可以,而在 Pycharm/保存为文件 执行,结果是不一样的,这是因为解释器做了一部分优化。即在使用pycharm时,即使整数超过 256,使用 is 也是成立的。

1-4 特例二:使用 is 时注意 python 关于字符串的 intern 机制存储

python 中虽然字符串对象也是不可变对象,但 python 有个 intern 机制,简单说就是维护一个字典,这个字典维护已经创建字符 (key) 和它的字符串对象的地址 (value),每次创建字符串对象都会和这个字典比较,没有就创建,重复了就用指针进行引用就可以了。相当于 python 对于字符串也是采用了对象池原理。

但是注意:如果字符串(含有空格),不可修改,没开启intern机制,不共用对象。比如"a b"和"a b"。

同样地,这种情况使用 is 不成立的形式只有在命令行中可以。使用pycharm 同样是 True,因为做了优化。

>>> s1, s2 = 'abc', 'abc'
>>> s1 is s2
True
>>> s1, s2 = 'a b', 'a b'
>>> s1 is s2
False

PS. 本小节参考了 Python中is与==的使用区别详解

2 matplotilb.pyplot 与 pylab 的联系与区别

根据 pyplot 源码 pyplot.py 中的解释部分就可得知:

matplotlib.pylab combines pyplot with numpy into a single namespace. 
This is convenient for interactive work, but for programming it is recommended that the namespaces be kept separate.

意思就是说 pylab 结合了 pyplot 和 numpy,对交互式使用来说比较方便,既可以画图又可以进行简单的计算。但是,对于一个项目来说,建议分别倒入使用,即:

import numpy as np
import matplotlib.pyplot as plt

而不是

import pylab as pl

附在使用matplotlib及相关模块时可能用得上的资料网址:

相关文章

  • 【Note】搬砖路上遇到的坑

    1 open() 和 codecs.open() 有什么区别吗? 首先,一提到用 python 读写文件估计大家都...

  • 【Note】搬砖路上遇到的坑

    1 关于内存管理的那些事(is VS ==) 首先,变量类型分为一下两个大类。 可变类型,值可以改变: 列表 li...

  • 搬砖-需要避免的坑

    关于如何搬砖的文章已经很多了,我作为一个刚入门的搬砖新手,总结了一些经常遇到的坑。尽量避免盲目搬砖砸到自己的脚,不...

  • 如何用软件自动搬砖实现睡后收入

    本文由币乎(bihu.com)优质内容计划支持 自动搬砖的原理 经过前面文章“区块链搬砖要避免哪些坑”和“搬砖的坑...

  • 原创诗歌【踏上搬砖路】

    文|搬砖哥 《踏上搬砖路》 人生是一场旅途 你我看不清未来 路上的我 生活几度落迫 但心中理想不变 搬砖哥遍布全国...

  • 搬砖 ‘搬砖’

    生儿生女有啥差别?听听院子里几位大妈的感慨,张大妈说:生女儿好,不用操心买车买房,生儿子的现在取媳妇都难,车、房、...

  • 搬砖路上的几点感悟

    1、践行践行再践行 要想在熊市赚到钱,搬砖应该算是一种很好的方法。作为区块链初学者,本人最近也学习了很多区块链投资...

  • Bitcoin Elven

    一、我为什么要研究搬砖 原因:穷 二、我是怎么搬砖的 搬砖的形式有很多种,主要就是硬搬砖和对冲搬砖,其中,硬搬砖是...

  • [区块链入门必备]第3期-法币搬砖

    法币搬砖是利润最高的搬砖方式,同时也是需要资源最多的搬砖方式。下面介绍两种常见的法币搬砖方式。 中韩法币搬砖 需要...

  • 零风险搬砖套利

    什么是搬砖? 首先我们来举个例子什么是搬砖? 搬砖:搬砖就是通过不同交易平台之间的差价来获利的行为就是搬砖, 在这...

网友评论

      本文标题:【Note】搬砖路上遇到的坑

      本文链接:https://www.haomeiwen.com/subject/uikupqtx.html