前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【入门必看】不理解「对象」?很可能有致命bug:简单的Python例子告诉你

【入门必看】不理解「对象」?很可能有致命bug:简单的Python例子告诉你

作者头像
Piper蛋窝
发布2020-12-15 10:51:31
3020
发布2020-12-15 10:51:31
举报
文章被收录于专栏:Piper蛋窝Piper蛋窝
简介:越来越多的人要在学习工作中用到『编程』这个工具了,其中很大一部分人用的是Python。大部分人只是做做简单的科研计算、绘图、办公自动化或者爬虫,但—— 这就不需要理解「指针与面向对象」了吗? 在我看来,新手或外行朋友也需要简单地理解「对象」概念,本文将先演示一个反例(告诉你不理解将多么容易犯错误),然后浅显地介绍一下「对象」。

致命bug

小垣坐在电脑前,一脸愁容——这么简单的程序,她花了3个小时,硬是没发现哪里不对,导致程序不通畅。

她发了几张截图给我,说“拍老师,发生甚么事了?”

我一看,嗷,是班花小垣给我发消息了,我啪一下站起来了,很快啊!

一共两个.py脚本文件,一个八十多行,一个九十多行。整体逻辑没什么问题,只是有几处很“荒唐”,究其原因,是小垣没有理解「对象」这个概念。

看罢,我抛开这个问题,直接甩给她我腾讯会议ID,开始讲解起「对象」这个概念来,因为了解了「对象」这个传统功夫后,其问题自然而然就化解了。

一个简单的 numpy 反例

我们以 Python 中最常用的矩阵与代数库 numpy 为例。

代码语言:javascript
复制
import numpy as np

我们现在定义一个长度为 3 的向量 vec_origin ,其中存放 1,2,3 。然后我们打印一下看看。

代码语言:javascript
复制
vec_origin = np.array([1, 2, 3])print(vec_origin)

打印结果如下。

代码语言:javascript
复制
[1 2 3]

假如我们需要复制一下向量 vec_origin ,那么,“自然”是做个等号。如下。然后打印一下。

代码语言:javascript
复制
vec_copy = vec_originprint(vec_copy)

输出结果为如下。

代码语言:javascript
复制
[1 2 3]

接下来, vec_originvec_copy 将参与不同的运算任务,其将被加减乘除,还有 赋值 。问题就出在了,如果我们为 vec_copy 赋值,那么 vec_origin 的值也将被改变。不信你试试下面的代码。

代码语言:javascript
复制
print("vec_origin", vec_origin)print("vec_copy", vec_copy)vec_copy[0] = 9print("我们只改变了 vec_copy 的值,但是:")print("vec_origin", vec_origin)print("vec_copy", vec_copy)

输出结果如下。

代码语言:javascript
复制
vec_origin [1 2 3]vec_copy [1 2 3]我们只改变了 vec_copy 的值,但是:vec_origin [9 2 3]vec_copy [9 2 3]

但是,vec_origin 的值也跟着改变了。这是为什么呀!

要知道,我们对变量赋值与复制,是不会改变原值的呀!如下。

代码语言:javascript
复制
a = 1b = aprint(a)  # 1print(b)  # 1b = 9print(a)  # 1print(b)  # 9

numpy 中的矩阵/向量,是个对象

对于 numpy 来讲,我们声明的矩阵或者向量,并不是一个“数字”那么简单,而是一个有「身份证」的『对象』。

一个对象可以有多个名字,但身份证只能有一个。换句话说,身份证才是唯一标识。

对于不是单个数值的数,我们的 = 赋值,只不过是 给对象新增了一个名字罢了。

不信,我们用 python 内置的 id() 函数看看 vec_originvec_copy 名字是不是一样的。

代码语言:javascript
复制
print(id(vec_origin))print(id(vec_copy))

结果如下。

代码语言:javascript
复制
20069718171362006971817136

很显然,二者的身份证是一个,这根本就是同一个向量。

对于 listdict 等等,都是同理。

那么,该如何复制呢?

我的建议是,你没有必要去刻意背诵方法。不同类型的对象有不同赋值方法。对于 numpy 的向量,我们去互联网搜索一下就好,检索词:numpy 复制

我查到的方法是:使用 np.copy

那么我们试验一下。

代码语言:javascript
复制
import numpy as npvec_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] = 9print("我们只改变了 vec_copy 的值,但是:")print("vec_origin", vec_origin)print("vec_copy", vec_copy)print(id(vec_origin))print(id(vec_copy))

结果如下。

代码语言:javascript
复制
vec_origin [1 2 3]vec_copy [1 2 3]我们只改变了 vec_copy 的值,但是:vec_origin [1 2 3]vec_copy [9 2 3]23439528173282343952817568

如你所见, np.copy 后,是新增了一个对象,而非仅仅是为原对象新增了一个变量名而已。

这是 零基础编程 系列的第一篇文章,之后,我们将用简单的例子讨论:面向对象指针数据结构等等基础概念。我一直认为,新手对这些概念有些许了解后,将少走很多很多的弯路。

最后,你问小垣有没有改好 bug ,那自然是:传统功夫点到为止!自从她跟我说她有「对象」后,我就再也没问过她有没有理解「对象」。

小垣同学,图源:GAKKI

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-11-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Piper蛋窝 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 致命bug
    • 一个简单的 numpy 反例
      • numpy 中的矩阵/向量,是个对象
        • 那么,该如何复制呢?
        相关产品与服务
        腾讯会议
        腾讯会议(Tencent Meeting)为企业打造专属的会议能力,卓越的音视频性能,丰富的会议协作能力,坚实的会议安全保障,提升协作效率,满足大中小会议全场景需求。您可以使用腾讯会议进行远程音视频会议、在线协作、会管会控、会议录制、指定邀请、布局管理、同声传译等。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档