【入门必看】不理解「对象」?很可能有致命bug:简单的Python例子告诉你
简介:越来越多的人要在学习工作中用到『编程』这个工具了,其中很大一部分人用的是Python。大部分人只是做做简单的科研计算、绘图、办公自动化或者爬虫,但—— 这就不需要理解「指针与面向对象」了吗? 在我看来,新手或外行朋友也需要简单地理解「对象」概念,本文将先演示一个反例(告诉你不理解将多么容易犯错误),然后浅显地介绍一下「对象」。
一个简单的 numpy 反例
我们以 Python 中最常用的矩阵与代数库 numpy 为例。
import numpy as np
复制代码
我们现在定义一个长度为 3 的向量 vec_origin ,其中存放 1,2,3 。然后我们打印一下看看。
vec_origin = np.array([1, 2, 3])
print(vec_origin)
复制代码
打印结果如下。
[1 2 3]
复制代码
假如我们需要复制一下向量 vec_origin ,那么,“自然”是做个等号。如下。然后打印一下。
vec_copy = vec_origin
print(vec_copy)
复制代码
输出结果为如下。
[1 2 3]
复制代码
接下来, vec_origin 与 vec_copy 将参与不同的运算任务,其将被加减乘除,还有 赋值 。问题就出在了,如果我们为 vec_copy 赋值,那么 vec_origin 的值也将被改变。不信你试试下面的代码。
print("vec_origin", vec_origin)
print("vec_copy", vec_copy)
vec_copy[0] = 9
print("我们只改变了 vec_copy 的值,但是:")
print("vec_origin", vec_origin)
print("vec_copy", vec_copy)
复制代码
输出结果如下。
vec_origin [1 2 3]
vec_copy [1 2 3]
我们只改变了 vec_copy 的值,但是:
vec_origin [9 2 3]
vec_copy [9 2 3]
复制代码
但是,vec_origin 的值也跟着改变了。这是为什么呀!
要知道,我们对变量赋值与复制,是不会改变原值的呀!如下。
a = 1
b = a
print(a) # 1
print(b) # 1
b = 9
print(a) # 1
print(b) # 9
复制代码
numpy 中的矩阵/向量,是个对象
对于 numpy 来讲,我们声明的矩阵或者向量,并不是一个“数字”那么简单,而是一个有「身份证」的『对象』。
一个对象可以有多个名字,但身份证只能有一个。换句话说,身份证才是唯一标识。
对于不是单个数值的数,我们的 = 赋值,只不过是 给对象新增了一个名字罢了。
不信,我们用 python 内置的 id() 函数看看 vec_origin 与 vec_copy 名字是不是一样的。
print(id(vec_origin))
print(id(vec_copy))
复制代码
结果如下。
2006971817136
2006971817136
复制代码
很显然,二者的身份证是一个,这根本就是同一个向量。
对于 list 、 dict 等等,都是同理。
那么,该如何复制呢?
我的建议是,你没有必要去可以背诵方法。不同类型的对象有不同赋值方法。对于 numpy 的向量,我们去互联网搜索一下就好,检索词:numpy 复制。
我查到的方法是:使用 np.copy 。
那么我们试验一下。
import numpy as np
vec_origin = np.array([1, 2, 3])
vec_copy = np.copy(vec_origin) # 这里复制
print("vec_origin", vec_origin)
print("vec_copy", vec_copy)
vec_copy[0] = 9
print("我们只改变了 vec_copy 的值,但是:")
print("vec_origin", vec_origin)
print("vec_copy", vec_copy)
print(id(vec_origin))
print(id(vec_copy))
复制代码
结果如下。
vec_origin [1 2 3]
vec_copy [1 2 3]
我们只改变了 vec_copy 的值,但是:
vec_origin [1 2 3]
vec_copy [9 2 3]
2343952817328
2343952817568
复制代码
如你所见, np.copy 后,是新增了一个对象,而非仅仅是为原对象新增了一个变量名而已。
这是 零基础编程 系列的第一篇文章,之后,我们将用简单的例子讨论:面向对象、指针、数据结构等等基础概念。我一直认为,新手对这些概念有些许了解后,将少走很多很多的弯路。
想要获取更多Python学习资料可以加我QQ:2955637827
【入门必看】不理解「对象」?很可能有致命bug:简单的Python例子告诉你的更多相关文章
- Java编程学习知识点分享 入门必看
Java编程学习知识点分享 入门必看 阿尔法颜色组成(alpha color component):颜色组成用来描述颜色的透明度或不透明度.阿尔法组成越高,颜色越不透明. API:应用编程接口.针对软 ...
- Liunx新手入门必看
安装CentOS(Linux的一个常用发行版本,互联网公司经常使用这个发行版)用到的软件: VMware_workstation_full_12.5.2.exe 虚拟机软件,虚拟机由这个软件安装.管理 ...
- JVM入门必看——JVM结构
转载自:http://blog.csdn.net/yfqnihao 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让 ...
- 入门必看--JavaScript基础
JavaScript他是一种描述性语言,其实他并不难学,只要用心学,一定会学好,我相信大家在看这篇文章的时候,一定也学过HTML吧,使用JavaScript就是为了能和网页有更好的交互,下面切入主题. ...
- HR问了一句DB是啥?SQL是啥?DB是Database数据库,SQL是数据库语言! 然后呢? 数据库从入门到精通--入门必看!
写在前面 本文的写作知识体系来源于我的数据库老师SDAU张承明,部分知识来自于网络,我呢对知识进行了细化和添加了自己的一些看法,并且加入了一些实例帮助理解,本文不是面向SQL高手写的,可以看作是数据库 ...
- 新手入门必看:VectorDraw 常见问题整理大全(一)
VectorDraw Developer Framework(VDF)是一个用于应用程序可视化的图形引擎库.有了VDF提供的功能,您可以轻松地创建.编辑.管理.输出.输入和打印2D和3D图形文件.该库 ...
- 全栈前端入门必看 koa2+mysql+vue+vant 构建简单版移动端博客
koa2+mysql+vue+vant 构建简单版移动端博客 具体内容展示 开始正文 github地址 <br/> 觉得对你有帮助的话,可以star一下^_^必须安装:<br/> ...
- Python字符串及基本操作(入门必看)
基础入门的知识一直没有更新完,今天小张接着给大家带来入门级的字符串的常用操作.本文适合刚入门的小白,大佬们请绕过. 一.定义 字符串的意思就是“一串字符”,比如“Hello,Charlie”是一个字符 ...
- vue 框架,入门必看
vue 的 入门 el 的挂载点: el 是用来设置vue实例挂载,(管理)的元素 vue会管理el选项命中的元素以及内部的后代元素 可以使用其他的选择器,但是不建议使用ID选择器 可以使用其他的双标 ...
随机推荐
- 模拟赛38 B. T形覆盖 大模拟
题目描述 如果玩过俄罗斯方块,应该见过如下图形: 我们称它为一个 \(T\) 形四格拼板 .其中心被标记为\(×\). 小苗画了一个 \(m\) 行 \(n\) 列的长方形网格.行从 \(0\) 至 ...
- 基于gin的golang web开发:永远不要相信用户的输入
作为后端开发者我们要记住一句话:"永远不要相信用户的输入",这里所说的用户可能是人,也可能是另一个应用程序."永远不要相信用户的输入"是安全编码的准则,也就是说 ...
- go特性-数组与切片
数组: 复制传递(不要按照c/c++的方式去理解,c/c++中数组是引用传递),定长 切片: 引用传递,底层实现是3个字段 array(数组) + len(长度) +cap(容量) type slic ...
- 【jvm】MinorGC和FullGC
新生代GC(Minor GC)指发生在新生代的垃圾收集动作,因为java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快. 老年代GC(MajorGC/Full GC) ...
- fastjson JSONObject简单使用
工作中用的蛮多的最近整理下,概括地说 通过这个工具可以让一个json在json串,JSONObject,java对象之间进行转化 首先我们先写2个bean来构成一个比较复杂的json串: public ...
- Java数据结构(十二)—— 霍夫曼树及霍夫曼编码
霍夫曼树 基本介绍和创建 基本介绍 又称哈夫曼树,赫夫曼树 给定n个权值作为n个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称为最优二叉树 霍夫曼树是带权路径长度最短的树,权值较 ...
- C#中From窗体判断提示框是否
int ret(变量名1) = command.ExecuteNonQuery(); if (ret(变量名1) > 0)//判断变量名是否大于0 { DialogResult dr(变量名2) ...
- 极简python教程02:基础变量,删繁就简
python极简教程已经开赛,如果错过说明可以回翻: 极简python教程:赛前说明 借这个机会,我再讲讲我的教程和其他网上的教程的区别: 1 我分享的内容,是我在工作中会高频使用的语法,是精华内容 ...
- moviepy音视频剪辑:mask clip遮罩剪辑、遮片、蒙版的作用以及其包含的构成内容
☞ ░ 前往老猿Python博文目录 ░ 在阅读moviepy的类ImageClip的构造方法代码时,对于其中涉及遮罩的处理没有理解,到处查找遮罩的资料没有查到,最后到moviepy的官网上尝试了一下 ...
- 老猿学5G:融合计费场景的离线计费会话的Nchf_OfflineOnlyCharging_Create创建操作
☞ ░ 前往老猿Python博文目录 ░ 一.Nchf_OfflineOnlyCharging_Create消息交互流程 Nchf_OfflineOnlyCharging_Create服务化操作请求是 ...