这些常见的坑,90%的程序猿都踩过,来看看里面有没有你的脚印?

学python的猫 等级 1517 0 0

在学习python的过程中,相信大家都有踩过不少的坑,有些坑可能踩了不止一次,感觉就像是在坑与坑之间反复横跳。那么如何避免这些坑呢?看完这篇文章,你就知道了。我们来谈谈我们学习python的过程中,最常见的七大坑这些常见的坑,90%的程序猿都踩过,来看看里面有没有你的脚印? 1. 缩进,符号和空格不正确 写代码时大家会使用缩进、对齐、空格等,这些是为了提高代码的可读性 在python语言中,缩进是十分重要的 比如在创建一个新类时,该类中的所有内容都在声明下缩进,决策、循环还有其它结构语句也会出现类似的情况, 代码执行时如果存在问题,可以先查看一下缩进是否正确。 这边有个例子,在使用IF语句时,请确保使用正确且合适的冒号和缩进,因为它们会导致语法和缩进错误。 val = 500 if val > 100 print("value is grater then 100") File "", line 2 if val > 100 ^ SyntaxError: invalid syntax 在上面的代码当中,出现了两处错误:if语句后面的:缺失;下一行没有进行正确的缩进,执行代码出错。 val = 500 if val > 100: print("value is grater then 100") value is grater then 100 更正这两个问题之后,代码可以很好的运行 2. 变量使用不正确 class A(object):x = 1 class B(A):pass class C(A):pass print( A.x, B.x, C.x) 1 1 1 这里输出的值都是1,然后我们试着来改变一下A.x和B.x的值看看有什么变化。 B.x = 2 print (A.x, B.x, C.x) A.x = 3 print (A.x, B.x, C.x) 1 2 1 3 2 3 我们只改变了A.x,为什么C.x改变呢? 这里需要了解到python的命名空间。 python中,命名空间是名字到对象映射的结合,不同命名空间中的名字是没有关联的,这种映射的实现有点类似于python中的字典。 当你名字访问一个对象的属性时,先从对象的命名空间寻找。如果找到了这个属性,就返回这个属性的值;如果没有找到的话,则从类的命名空间中寻找,找到了就返回这个属性的值,找不到则抛出异常。 在Python中,类变量在内部作为字典处理,并遵循通常称为方法解析顺序(MRO)的方法。 MRO:Method Resolution Order方法解析顺序,Python支持多继承,该方法用于解决父类存在同名函数的时存在的二义性问题。 因此在上面的代码中,由于x在对象的命名空间中找不到该属性C,因此将在类中查找它。换句话说,C没有自己的x属性,独立于A。因此,引用C.x实际上是指A.x。 3.不了解python范围规则 倘若不知道python的范围规则,那么犯错误的可能性会大大增加,这是因为Python使用一种独有的范围规则来确定变量范围。 python范围解析是基于LEGB规则,以下是Python范围规则的概述: ·L -代表Local。它包含在函数内指定的(标识符/变量)名称(使用def或lambda),而不是使用global关键字声明。 ·E -代表Enclosing function locals。它包含来自任何/所有封闭函数的本地范围的名称(例如,使用def或lambda)。 ·G -指全球实体。它包括在模块文件的顶层运行或使用global关键字定义的名称。 ·B -指内置插件。它跨越预先指定为内置名称的名称,如打印,输入,打开等。 LEGB规则指定名称空间的以下顺序,用于搜索名称: Local - > Enclosed - > Global - > Built-in 考虑以下的例子: x = 10 def foo(): x += 1 print(x) foo() UnboundLocalError Traceback (most recent call last): in in foo() UnboundLocalError: local variable xreferenced before assignment 发生上述错误的原因是,对作用域中的变量进行赋值时,Python会自动将该变量视为该作用域的本地变量,并在外部作用域中隐藏任何类似命名的变量。 因此,许多人在代码提示出错并显示需要在函数中添加赋值语句而感到不解。 考虑一个在使用列表时遇到的例子: lst = [1, 2, 3] def foo1(): lst.append(5) foo1() lst [1, 2, 3, 5] lst = [1, 2, 3] def foo2(): lst += [5] foo2() UnboundLocalError Traceback (most recent call last): in in foo2() UnboundLocalError: local variable lstreferenced before assignment 为什么foo2出错了但是foo1运行良好? 答案在前面就已经有所提示,在这个例子当中foo1()做一个分配到lst,而在foo2()当中lst += [5]其实只是lst = lst + [5]的简写,我们希望分配一个值给lst,但是分配的值lst是基于lst自身,但其尚未定义。 4. python闭包变量绑定 python的闭包变量问题也是新手们容易混淆的一个点,来看看下面的例子: def create_multipliers(): return [lambda x : i * x for i in range(5)] for multiplier in create_multipliers(): print (multiplier(2)) 8 8 8 8 8 为什么结果是88888,和我所想的02468不一样呢? 这是由于Python的迟绑定(late binding)机制,闭包中内部函数的值只有在被调用时才会进行查询。 因此create_multipliers函数返回的lambda函数被调用时,会在附近的作用域中查询变量i的值,而在create_multipliers生成返回数组之后,整数i的值是4,不会再改变,因此返回数组中每个匿名函数实际上都是:lambda x: 4x。、 解决办法是将临时值也保存在匿名函数的作用域内,在声明匿名函数时就查询变量的值。 了解原理之后,让我们来改一改代码,surprise! def create_multipliers(): return [lambda x, i=i : i * x for i in range(5)] for multiplier in create_multipliers(): print (multiplier(2)) 0 2 4 6 8 *5. 名称与Python标准库模块发生冲突** Python拥有大量的库模块,开箱即用。但是,如果您遇到一个模块的名称与Python附带的标准库中具有相同名称的模块之间的名称冲突,则可能会出现问题。 例如导入另一个库,而这个库又会尝试导入模块的Python标准库版本,但由于你有一个同名的模块,另一个包会错误地导入你的版本而不是Python标准库。 因此,应该注意避免使用与Python标准库模块中相同的名称,并且更改包中的模块名称比提交Python Enhancement Proposal(PEP)以请求名称更改更容易。 6.is和==/=和== Python中有很多运算符,例如is,=,==这三个,许多刚刚入门的新手会误解这三个运算符的意义和用法,以致于代码出错。 在 Python 中会用到对象之间比较,可以用 ==,也可以用 is,但对对象比较判断的内容并不相同,区别在哪里? ·is 比较两个对象的 id 值是否相等,是否指向同一个内存地址,== 比较的是两个对象的内容是否相等,值是否相等; a = ["Python"] b = a b is a True id(a) 2222222 id(b) 2222222 b == a True 可以发现上面的例子当中b和a的内存地址是相同的,它们指向同一块内存,因而 is 和 == 的结果都为True,这是因为直接赋值都是赋值的引用。如果新建对象之后,b 和 a 指向了不同的内存,那么 b is a 的结果为False,而 b==a的结果为True。 ·小整数对象[-5,256]在全局解释器范围内被放入缓存供重复使用,例如: a = 1 b = 1 a is b True a == b True a = 257 b = 257 a is b False Python仅仅对比较小的整数对象进行缓存(范围为范围[-5, 256])缓存起来,而并非是所有整数对象。需要注意的是,这仅仅是在命令行中执行,而在Pycharm或者保存为文件执行,结果是不一样的,这是因为解释器做了一部分优化。 =和==的含义不同: =代表的含义是赋值,将某一数值赋给某个变量,比如a=3,将3这个数值赋予给a。 ==是判断是否相等,返回True或False,比如1==1。他们是相等的,那么就返回true。1==2,他们是不相等的,那么就返回false。 例子: a = [1,2] b = [1,2] c = a a is b False a is c true a == b true 7. 滥用init init方法在Python中用作构造函数,当Python将内存分配给新的类对象时,它会自动被调用。 首先,init并不相当于C#中的构造函数,在执行它的时候,实例已经构造出来。 class A(object): def init(self,name): self.name=name def getName(self): return A+self.name 执行代码: a=A(hello) 可以理解为: a=object.new(A) A.init(a,hello) 即init作用是初始化已实例化后的对象。 其次,子类可以不重写init,实例化子类时,会自动调用超类中已定义的init。 class B(A): def getName(self): return B+self.name if name==main: b=B(hello) print (b.getName()) 但如果重写了init,实例化子类时,则不会隐式的再去调用超类中已定义的init。 class C(A): def init(self): pass def getName(self): return C+self.name if name==main: c=C() print (c.getName()) 此时执行代码则会报"AttributeError: C object has noattribute name ”错误,所以如果重写了init,为了能使用或扩展超类中的行为,最好显式的调用超类的init方法。 class C(A): def init(self,name): super(C,self).init(name) def getName(self): return C+self.name if name==main: c=C(hello) print (c.getName()) 这些常见的坑,90%的程序猿都踩过,来看看里面有没有你的脚印? 老天爷都给我点赞了,你还不点?觉得这篇文章对你有所帮助的话可以来个一键三连呀!!若有指正的话可以评论区见或者私我呀。

收藏
评论区

相关推荐

python文件的第一行 #!/usr/bin/python3 是什么意思?
python文件的第一行代码通常在脚本语言的第一行会看到: !/usr/bin/env python或 !/usr/bin/python 首先要确定的一点是它不是注释。这两句话的目的都是指出你的python文件用什么可执行程序去运行它。1. !/usr/bin/python 是告诉操作系统执行这个脚本的时候,调用 /usr/bin 下的 python 解释
三行Python程序代码实现MP4视频转GIF动画文件
一、引言最近看到好几篇类似“n行Python代码…”的博文,看起来还挺不错,简洁、实用,传播了知识、带来了阅读量,撩动了老猿的心,决定跟风一把,写个视频转动画的三行代码的极简实现。 二、moviepy2.1、moviepy介绍要实现视频转动画,老猿使用了moviepy库。 MoviePy是一个用于视频编辑的Python模块,可用于进行视频的基本操作(如剪
学python?我入门才七天
怎么自学python,大概要多久?我专科学的机械,在毕业之前完全没有接触过编程,毕业后从零开始学习python,所以在这方面我或许可以说上那么一两句话。第一,你需要明确一个目标。你是想做一个网站?还是说做一个自己用的工具,这会影响你如何去学习python,是否学到一定程度该转去学另一种语言?这都和你想做的事有关系,如果你是希望学习python写一些小工具来提
这些常见的坑,90%的程序猿都踩过,来看看里面有没有你的脚印?
在学习python的过程中,相信大家都有踩过不少的坑,有些坑可能踩了不止一次,感觉就像是在坑与坑之间反复横跳。那么如何避免这些坑呢?看完这篇文章,你就知道了。我们来谈谈我们学习python的过程中,最常见的七大坑:1. 缩进,符号和空格不正确写代码时大家会使用缩进、对齐、空格等,这些是为了提高代码的可读性在python语言中,缩进是十分重要的比如在创建一个新
2019独角兽企业重金招聘Python工程师标准
很多盆友一定有这样的疑问: **Python****是什么?** **学会了Python可以做什么?** **为什么人人都应该懂Python?** ![](https://oscimg.oschina.net/oscnet/f7ddd56eca5709e45b4b95cc1d9c9bc5d20.jpg) 别急,我来科普啦~ Python是一门面向
2019独角兽企业重金招聘Python工程师标准
很多盆友一定有这样的疑问: **Python****是什么?** **学会了Python可以做什么?** **为什么人人都应该懂Python?** ![](https://oscimg.oschina.net/oscnet/f7ddd56eca5709e45b4b95cc1d9c9bc5d20.jpg) 别急,我来科普啦~ Python是一门面向
25条很棒的Python一行代码,建议收藏!
点击上方“ **Python爬虫与数据挖掘** ”,进行关注 回复“**书籍**”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 中岁颇好道,晚家南山陲。 自从我用Python编写第一行代码以来,就被它的简单性、出色的可读性和特别流行的一行代码所吸引。 在下面,我将给大家介绍并解释一些Python一行程序。
ATP的OpenCV笔记(一):对图片的基本操作
##写在前面 ATP成功进化成弃坑大师。。 主要是正式开课以后自己乱搞着玩儿的东西就不想管它了QAQ。。。Python学会了以后也懒得往博客里写了。。 这次打算开的坑emmm是上课讲的内容?由于要记住的函数用法太多ATP懒得每次遇到都百度所以相当于在blog里面记一下嗯就是这样。 OpenCV是个可以用来做图像处理的库?在C++和python里面都有
Centos服务器中多版本Python带来的困惑问题
最近写了几个在crond中使用的python定时执行脚本。其中使用了datetime包中的timedelta的total\_seconds()方法。配置定时执行的方式也很简单,就写成了 \*/5 \* \* \* \* root python abc.py 写好后,发现定时执行的脚本每次执行都会报错,说找不到total\_seconds方法。在脚本中导入
Copy攻城狮辛酸史:含泪“一分钟”跑通MindSpore的LeNet模型
> **摘要:**一个Cope 攻城狮用切身实例告诉你: Cope代码体验一时爽,BUG修改花半天。 前言:此文为r0.7-beta的操作实践,为什么我的眼里常含泪水,因为我对踩坑这件事爱得深沉。谨以此文献给和我一样踩坑的小伙伴,纪念踩坑时刻。 ![](https://pic2.zhimg.com/80/v2-0c653151d9ddd33a2a2622
Flask教程(十五)日志
### 软硬件环境 * windows 10 64bit * anaconda3 with python 3.7 * pycharm 2020.1.2 * flask 1.1.2 ### 简介 `flask`日志使用标准的`python``logging`。所有与`flask`相关的消息都用`ap
Python web开发从入门到放弃
点击上方“**Python爬虫与数据挖掘**”,进行关注 回复“**书籍**”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 无为之用方为大用。 ![](https://oscimg.oschina.net/oscnet/f64430c27950bcccce040bb032ea65e73a5.jpg) 越来越多的同学知道我在做
Python 函数为什么会默认返回 None?
点击蓝色“Python空间”关注我丫 加个“星标”,每天一起快乐的学习 ![](https://oscimg.oschina.net/oscnet/2eb7387a-d87b-4685-a8b2-a60f61773c78.jpg) Python 有一项默认的做法,很多编程语言都没有——**它的所有函数都会有一个返回值,不管你有没有写 retur
Python基础:四、python的优缺点
python是一门动态解释性的强类型语言 -------------------- ### python的优点: **1\. python的定位是"优雅"、"明确"、"简单"**         python程序看上去总是简单易懂,初学者学python,不但入门容易,二缺将来深入下去,可以边啊些那些非常复杂的程序。 **2\. 开发效率高**  
Python编程规范修炼
**“**Guido van Rossum(吉多·范罗苏姆,Python 创始人 )说过,代码的阅读频率远高于编写代码的频率。毕竟,即使是在编写代码的时候,你也需要对代码进行反复阅读和调试,来确认代码能够按照期望运行。**”** 接下来我们今天就为大家分享《Python编程规范:让你的代码脚下生风》第三弹《Google开源项目风