python开发中遇到的难题_初学者在Python开发中常见的问题(上)

前言:这篇文章主要介绍了Python程序员代码编写时应该避免的17个“坑”,也是Python程序员代码编写时应该避免的17个问题,如果有知友想要了解Python,文末有黑马程序员的Python免费教程,需要的知友可以参考一下~如果喜欢请点赞哈

一、不要使用可变对象作为函数默认值

[url=]复制代码[/url]代码如下:

In [1]: def append_to_list(value, def_list=[]):

...: def_list.append(value)

...: return def_list

...:

In [2]: my_list = append_to_list(1)

In [3]: my_list

Out[3]: [1]

In [4]: my_other_list = append_to_list(2)

In [5]: my_other_list

Out[5]: [1, 2] # 看到了吧,其实我们本来只想生成[2] 但是却把第一次运行的效果页带了进来

In [6]: import time

In [7]: def report_arg(my_default=time.time()):

...: print(my_default)

...:

In [8]: report_arg() # 第一次执行

1399562371.32

In [9]: time.sleep(2) # 隔了2秒

In [10]: report_arg()

1399562371.32 # 时间竟然没有变

这2个例子说明了什么? 字典,集合,列表等等对象是不适合作为函数默认值的. 因为这个默认值实在函数建立的时候就生成了, 每次调用都是用了这个对象的”缓存”. 我在上段时间的分享python高级编程也说到了这个问题,这个是实际开发遇到的问题,好好检查你学过的代码, 也许只是问题没有暴露

可以这样改:

[url=]复制代码[/url]代码如下:

def append_to_list(element, to=None):

if to is None:

to = []

to.append(element)

return to

二、生成器不保留迭代过后的结果

[url=]复制代码[/url]代码如下:

In [12]: gen = (i for i in range(5))

In [13]: 2 in gen

Out[13]: True

In [14]: 3 in gen

Out[14]: True

In [15]: 1 in gen

Out[15]: False # 1为什么不在gen里面了? 因为调用1->2,这个时候1已经不在迭代器里面了,被按需生成过了

In [20]: gen = (i for i in range(5))

In [21]: a_list = list(gen) # 可以转化成列表,当然a_tuple = tuple(gen) 也可以

In [22]: 2 in a_list

Out[22]: True

In [23]: 3 in a_list

Out[23]: True

In [24]: 1 in a_list # 就算循环过,值还在

Out[24]: True

三、lambda在闭包中会保存局部变量

[url=]复制代码[/url]代码如下:

In [29]: my_list = [lambda: i for i in range(5)]

In [30]: for l in my_list:

....: print(l())

....:

4

4

4

4

4

这个问题还是上面说的python高级编程中说过具体原因. 其实就是当我赋值给my_list的时候,lambda表达式就执行了i会循环,直到 i =4,i会保留

但是可以用生成器

[url=]复制代码[/url]代码如下:

In [31]: my_gen = (lambda: n for n in range(5))

In [32]: for l in my_gen:

....: print(l())

....:

0

1

2

3

4

也可以坚持用list:

[url=]复制代码[/url]代码如下:

In [33]: my_list = [lambda x=i: x for i in range(5)] # 看我给每个lambda表达式赋了默认值

In [34]: for l in my_list:

....: print(l())

....:

0

1

2

3

4

有点不好懂是吧,在看看python的另外一个魔法:

[url=]复制代码[/url]代码如下:

In [35]: def groupby(items, size):

....: return zip(*[iter(items)]*size)

....:

In [36]: groupby(range(9), 3)

Out[36]: [(0, 1, 2), (3, 4, 5), (6, 7, 8)]

一个分组的函数,看起来很不好懂,对吧? 我们来解析下这里

[url=]复制代码[/url]代码如下:

In [39]: [iter(items)]*3

Out[39]:

[,

,

] # 看到了吧, 其实就是把items变成可迭代的, 重复三回(同一个对象哦), 但是别忘了,每次都.next(), 所以起到了分组的作用

In [40]: [lambda x=i: x for i in range(5)]

Out[40]:

[>,

>,

>,

>,

>] # 看懂了吗?

四、在循环中修改列表项

[url=]复制代码[/url]代码如下:

In [44]: a = [1, 2, 3, 4, 5]

In [45]: for i in a:

....: if not i % 2:

....: a.remove(i)

....:

In [46]: a

Out[46]: [1, 3, 5] # 没有问题

In [50]: b = [2, 4, 5, 6]

In [51]: for i in b:

....: if not i % 2:

....: b.remove(i)

....:

In [52]: b

Out[52]: [4, 5] # 本来我想要的结果应该是去除偶数的列表

思考一下,为什么 – 是因为你对列表的remove,影响了它的index

[url=]复制代码[/url]代码如下:

In [53]: b = [2, 4, 5, 6]

In [54]: for index, item in enumerate(b):

....: print(index, item)

....: if not item % 2:

....: b.remove(item)

....:

(0, 2) # 这里没有问题 2被删除了

(1, 5) # 因为2被删除目前的列表是[4, 5, 6], 所以索引list[1]直接去找5, 忽略了4

(2, 6)

五、IndexError - 列表取值超出了他的索引数

[url=]复制代码[/url]代码如下:

In [55]: my_list = [1, 2, 3, 4, 5]

In [56]: my_list[5] # 根本没有这个元素

---------------------------------------------------------------------------

IndexError Traceback (most recent call last)

in ()

----> 1 my_list[5]

IndexError: list index out of range # 抛异常了

In [57]: my_list[5:] # 但是可以这样, 一定要注意, 用好了是trick,用错了就是坑啊

Out[57]: []

六、重用全局变量

[url=]复制代码[/url]代码如下:

In [58]: def my_func():

....: print(var) # 我可以先调用一个未定义的变量

....:

In [59]: var = 'global' # 后赋值

In [60]: my_func() # 反正只要调用函数时候变量被定义了就可以了

global

In [61]: def my_func():

....: var = 'locally changed'

....:

In [62]: var = 'global'

In [63]: my_func()

In [64]: print(var)

global # 局部变量没有影响到全局变量

In [65]: def my_func():

....: print(var) # 虽然你全局设置这个变量, 但是局部变量有同名的, python以为你忘了定义本地变量了

....: var = 'locally changed'

....:

In [66]: var = 'global'

In [67]: my_func()

---------------------------------------------------------------------------

UnboundLocalError Traceback (most recent call last)

in ()

----> 1 my_func()

in my_func()

1 def my_func():

----> 2 print(var)

3 var = 'locally changed'

4

UnboundLocalError: local variable 'var' referenced before assignment

In [68]: def my_func():

....: global var # 这个时候得加全局了

....: print(var) # 这样就能正常使用

....: var = 'locally changed'

....:

In [69]: var = 'global'

In [70]:

In [70]: my_func()

global

In [71]: print(var)

locally changed # 但是使用了global就改变了全局变量

七、拷贝可变对象

[url=]复制代码[/url]代码如下:

In [72]: my_list1 = [[1, 2, 3]] * 2

In [73]: my_list1

Out[73]: [[1, 2, 3], [1, 2, 3]]

In [74]: my_list1[1][0] = 'a' # 我只修改子列表中的一项

In [75]: my_list1

Out[75]: [['a', 2, 3], ['a', 2, 3]] # 但是都影响到了

In [76]: my_list2 = [[1, 2, 3] for i in range(2)] # 用这种循环生成不同对象的方法就不影响了

In [77]: my_list2[1][0] = 'a'

In [78]: my_list2

Out[78]: [[1, 2, 3], ['a', 2, 3]]

八、python多继承(C3)

[url=]复制代码[/url]代码如下:

In [1]: class A(object):

...: def foo(self):

...: print("class A")

...:

In [2]: class B(object):

...: def foo(self):

...: print("class B")

...:

In [3]: class C(A, B):

...: pass

...:

In [4]: C().foo()

class A # 例子很好懂, C继承了A和B,从左到右,发现A有foo方法,返回了

看起来都是很简单, 有次序的从底向上,从前向后找,找到就返回. 再看例子:

[url=]复制代码[/url]代码如下:

In [5]: class A(object):

...: def foo(self):

...: print("class A")

...:

In [6]: class B(A):

...: pass

...:

In [7]: class C(A):

...: def foo(self):

...: print("class C")

...:

In [8]: class D(B,C):

...: pass

...:

In [9]: D().foo()

class C # ? 按道理, 顺序是 D->B->A,为什么找到了C哪去了

这也就涉及了MRO(Method Resolution Order):

[url=]复制代码[/url]代码如下:

In [10]: D.__mro__

Out[10]: (__main__.D, __main__.B, __main__.C, __main__.A, object)

简单的理解其实就是新式类是广度优先了, D->B, 但是发现C也是继承A,就先找C,最后再去找A。

向大家推荐两套免费黑马程序员Python经典入门教程,喜欢的可以收藏一下或者推荐给身边的朋友:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/434957.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用网上下载的arcgis工具箱,报错汇总

执行网格表达式错误 解决方法 更改环境变量里的并行处理设置成0即可

基于 Android NDK 的学习之旅-----环境搭建

工欲善其事 必先利其器 , 下面介绍下 Eclipse SDK NDK Cygwin CDT 集成开发环境的搭建。 1、Android 开发环境搭建 Android开发环境搭建不是重点,相信看此文章的很多人都已经搭建成功,这里随便概述性的说说。 1) 下载 JDK 2) 下载 Eclipse 3) 下载 Android…

arcgis将小于0的数值设置成0.01

原始范围 打开栅格计算器 主要利用的是栅格计算器的con条件函数 con用法 con(条件,满足条件的部分赋值赋值,不满足条件的部分赋值) 运行完的范围 0.0008<0.01所以显示0.0008

vivo怎么调时间_卡西欧手表怎么调时间 怎么评估卡西欧手表的价格档次

在以前的手表是戴在手上方便看时间的&#xff0c;但是随着科技的发展&#xff0c;手表也越来越智能&#xff0c;很多的手表都是多功能的&#xff0c;但是我们的知道&#xff0c;一样东西越好用就会显得它的复杂性越高&#xff0c;慢慢着就会使很多人都不会使用&#xff0c;就拿…

PJSIP学习笔记——PJSUA层发起呼叫的主要流程

在上一篇学习笔记 从simple_pjsua.c示例程序了解PJSUA-LIB的基本使用流程中&#xff0c;使用了PJSUA层的 pjsua_call_make_call来发起一个呼叫&#xff0c;那么这个发起呼叫的流程是怎样的呢&#xff1f;先来看看这个函数&#xff1a; [cpp] view plaincopy/* * Make outgoin…

Jquery Money 验证,转换成千分位

function Convert(amtStr) {var a, renum ;var j 0;var a1 , a2 , a3 ;var tes /^-/;a amtStr.replace(/,/g, "");a a.replace(/[^-\.,0-9]/g, ""); //删除无效字符a a.replace(/(^\s*)|(\s*$)/g, ""); //trimif (tes.test(a)) a1 -;e…

离职证明电子版_离职证明中说劳动者因违纪离职的怎么办?

作者&#xff1a;吕武茂 衣尚民 范涛1.律师有话说&#xff1a;根据法律规定&#xff0c;解除或终止劳动合同后&#xff0c;给员工开离职证明是企业的法定义务&#xff0c;离职证明内容仅包括&#xff1a;劳动合同期限、解除或者终止劳动合同的日期、工作岗位、在本单位的工作年…

sip消息概念(一)

SIP 也是类似 HTTP 的一个协议集合&#xff0c;在网上搜索了一下相关的信息&#xff0c;摘录如下&#xff1a; SIP消息的第一行包含消息的类型和所使用的SIP版本&#xff08;2.0&#xff09;。在请求中&#xff0c;这一行还包含一个叫做SIP URI的地址。这代表消息的目的地。 这…

python特征递归消除

一、基础知识了解 特征递归消除官方给了两者方法 1.RFE 2.RFECV 一.RFE 官方解释 链接&#xff1a;sklearn.feature_selection.RFE — scikit-learn 1.0.2 documentationhttps://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.RFE.html?highligh…

SIP 中的Dialog,call,session 和 transaction .

如果你对Sip协议中Call, Dialog, Transaction和Message之间的关系感觉到迷惑,那么,那么我可以告诉你,你并不孤单,因为大多数初学者对于这些名词之间的关系都会感到疑惑.Messages(消息) 消息是在服务器和客户端之间交换的独立文本, 有两种类型的消息,分别是请求(Requests)和响应…

JS 获取当前日期时间(兼容IE FF)

以前在页面中获得当前时间的方法如下&#xff1a; function SelectTodayClient() {var d new Date();var taday d.getYear() "-" (d.getMonth() 1) "-" d.getDate(); alert($(taday);} IE运行正常&#xff0c;FF运行如下&#xff1a; 这…

再次携号转网_潍坊一小伙欲携号转网屡被拒 联通客服:试运营状态不支持携转...

携号转网&#xff0c;也就是在手机号码保持不变的情况下&#xff0c;可以更换运营商&#xff0c;潍坊市民夏先生给记者打来电话说&#xff0c;他有一张联通的电话卡&#xff0c;想要办理携号转网业务&#xff0c;十几天过去了&#xff0c;号没转出去&#xff0c;还生了一肚子气…

机器学习参数优化数据改用所有数据还是训练集

参数优化过程中所用数据应该用训练集 &#xff08;占所有数据的一部分&#xff09;&#xff0c;如果用所有数据会导致模型评估的所有结果都偏高&#xff0c;因为这些评估都涉及测试集&#xff0c;如果用所有数据进行训练&#xff0c;导致测试集预测结果大部分都正确&#xff0c…

《当程序员的那些狗日日子》(三十六)无名的配角

人事助理姐姐帮我办理完续签手续后&#xff0c;我也回到原来的工作状态&#xff0c;继续处理手上的工作。 之前洪协助我完成了客服后台的一些新功能&#xff0c;但是在投入使用后&#xff0c;我发现这些功能还是存在较大的问题&#xff0c;本来我以为就要离开公司了&#xff0c…

8个树莓派超级计算机_6 个可以尝试的树莓派教程

这些树莓派项目均旨在简化你的生活并提高生产力。-- Lauren Pritchett(作者)没有什么比体验树莓派创作结果更令人兴奋了。经过数小时的编程、测试和徒手构建&#xff0c;你的项目终于开始成形&#xff0c;你不禁大喊 “哇哦&#xff01;”树莓派可以带给日常生活的可能性让我着…

SIP应答消息状态码与功能

SIP应答消息状态码与功能 类型 状态码 状态说明 临时应答(1XX) 100 Trying 正在处理中 180 Ringing 振铃 181 call being forwarder 呼叫正在前向 182 queue 排队 181* session progress 会话进行 会话成功(2XX) 200 OK 会话成功 重定向(3XX) 300 multiple 多重选择 301 moved …

sklearn的逻辑回归

官方逻辑回归链接 sklearn.linear_model.LogisticRegression — scikit-learn 1.0.2 documentationhttps://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html#sklearn.linear_model.LogisticRegression 一&#xff0c;参数说明 1.1…

Ext scope 学习

首先&#xff0c;用一句话来概括scope的作用&#xff1a;scope就是用来解决 js 中 this 的指向问题。 下面进行讨论&#xff1a; 1、 关于JavaScript中this的使用&#xff0c;这是一个由来已久的问题了。我们这里就不介绍它的发展历史了&#xff0c;只结合具体的例子&#xff…

python某公司为员工发放奖品_python 练习2

#######假定有下面这样的列表:names [fentiao, fendai, fensi, apple]输出结果为:I have fentiao, fendai, fensi and apple.names [fentiao, fendai, fensi, apple]print I have ,.join(names[:-1]) and names[-1]######系统里面有用户 用户有密码users [root,westos…