博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python编码错误_学习用Python编码时要避免的3个错误
阅读量:2526 次
发布时间:2019-05-11

本文共 5049 字,大约阅读时间需要 16 分钟。

python编码错误

做错事绝非易事,但犯错是任何学习过程的一部分,从学习走路到学习新的编程语言(例如Python)。

这里列出了我在学习Python时出错的三件事,以使新的Python程序员可以避免犯同样的错误。 这些错误或者是我很久以前就解决的,或者是造成了需要花费数小时才能解决的重大问题的错误。

请注意年轻的编码员,其中一些错误是浪费下午的时间!

1.可变数据类型作为函数定义中的默认参数

有道理吧? 假设您有一个小功能,可以搜索当前页面上的链接并将其附加到另一个提供的列表中。

def search_for_links      
( page
, add_to
=
[
]
) :
    new_links
= page.
search_for_links
(
)
    add_to.
extend
( new_links
)
   
return add_to

从表面上看,这看起来像是完全正常的Python,确实如此。 有用。 但是有问题。 如果我们提供了add_to参数的列表,它将按预期工作。 但是,如果我们使用默认值,则会发生一些有趣的事情。

尝试以下代码:

def fn      
( var1
, var2
=
[
]
) :
    var2.
append
( var1
)
   
print var2
fn
(
3
)
fn
(
4
)
fn
(
5
)

您可能希望我们会看到:

[3]

[4]
[5]

但是我们实际上看到了这一点:

[3]

[3,4]
[3,4,5]

为什么? 好了,您看到的是,每次都使用相同的列表。 在Python中,当我们以这种方式编写函数时,列表将作为函数定义的一部分实例化。 每次运行该函数时都不会实例化它。 这意味着该函数将一次又一次地使用完全相同的列表对象,除非我们当然提供另一个对象:

fn ( 3 , [ 4 ] )

[4,3]

符合预期。 实现所需结果的正确方法是:

def fn      
( var1
, var2
=
None
) :
   
if
not var2:
        var2
=
[
]
    var2.
append
( var1
)

或者,在我们的第一个示例中:

def search_for_links      
( page
, add_to
=
None
) :
   
if
not add_to:
        add_to
=
[
]
    new_links
= page.
search_for_links
(
)
    add_to.
extend
( new_links
)
   
return add_to

这会将实例化从模块加载时间移开,以使其在每次函数运行时发生。 请注意,对于不可变的数据类型(例如 , 或 ,这不是必需的。 这意味着可以执行以下操作:

def func      
( message
=
"my message"
) :
   
print message

2.可变数据类型作为类变量

紧跟着最后一个错误的是一个非常相似的错误。 考虑以下:

class URLCatcher      
( object
)
:
    urls
=
[
]
    def add_url
(
self
, url
)
:
       
self
. urls
. append
( url
)

这段代码看起来很正常。 我们有一个带有URL存储的对象。 当我们调用add_url方法时,它会将给定的URL添加到商店中。 完美吧? 让我们来看看它的作用:

a      
= URLCatcher
(
)
a.
add_url
(
'http://www.google.'
)
b
= URLCatcher
(
)
b.
add_url
(
'http://www.bbc.co.'
)

b.urls

[' ']

网址

[' ']

等等,什么? 我们没想到。 我们实例化了两个单独的对象ab为A提供了一个URL,为b提供了另一个URL。 两个对象都有两个URL怎么办?

事实证明,这与第一个示例有点相同。 创建类定义时,将实例化URL列表。 该类的所有实例都使用相同的列表。 现在,在某些情况下这是有利的,但是大多数时候您不想这样做。 您希望每个对象都有一个单独的存储。 为此,我们将修改如下代码:

class URLCatcher      
(
object
) :
   
def
__init__
(
self
) :
       
self .
urls
=
[
]
   
def add_url
(
self
, url
) :
       
self .
urls .
append
( url
)

现在,在创建对象时实例化URL列表。 当我们实例化两个单独的对象时,它们将使用两个单独的列表。

3.可变的分配错误

这使我困惑了一段时间。 让我们稍微改变一下齿轮,使用另一个可变的数据类型 。

a      
=
{
'1' :
"one"
,
'2' :
'two'
}

现在让我们假设我们要采取字典和其他人使用它的某个地方,离开原来的不变。

b      
= a
b
[
'3'
]
=
'three'

简单吗?

现在让我们看一下我们最初的字典a ,我们不想修改的字典:

{
'1' : "one" , '2' : 'two' , '3' : 'three' }

哇,等一下。 那么b是什么样子?

{
'1' : "one" , '2' : 'two' , '3' : 'three' }

等等什么 但是……让我们退后一步,看看其他不可变类型(例如元组)会发生什么:

c      
=
(
2
,
3
)
d
= c
d
=
(
4
,
5
)

现在c是:

(2、3)

d是:

(4、5)

可以正常运行。 那么在我们的示例中发生了什么? 当使用可变类型,我们得到的东西,表现得有点更像C的指针。当我们说b在上面,我们真正的意思是代码= A:B现在也是一个参考。 它们都指向Python内存中的同一对象。 听起来有点熟? 那是因为它与先前的问题相似。 实际上,该帖子实际上应该被称为“可变因素的麻烦”。

列表也会发生同样的事情吗? 是。 那么我们如何解决呢? 好吧,我们必须非常小心。 如果我们确实需要复制列表进行处理,则可以执行以下操作:

b = a [ : ]

这将遍历并将引用复制到列表中的每个项目,并将其放置在新列表中。 但请注意:如果列表中的任何对象都是可变的,我们将再次获得对这些对象的引用,而不是完整的副本。

想象一下在一张纸上有一张清单。 在原始示例中,人员A和人员B看着同一张纸。 如果有人更改了该列表,则两个人都会看到相同的更改。 当我们复制引用时,每个人现在都有自己的列表。 但让我们假设此列表包含寻找食物的地方。 如果“冰箱”在列表中位于第一位,即使复制后,两个列表中的两个条目都指向同一台冰箱。 因此,如果人A修改了冰箱,比如说吃了一个大的奶油蛋糕,那么人物B也将看到奶油蛋糕丢失了。 解决这个问题没有简单的方法。 您只需要记住并以不会引起问题的方式进行编码即可。

Dicts的功能相同,您可以执行以下操作来创建此昂贵的副本:

b = a. copy ( )

同样,这只会创建一个新字典,指向与原始字典中相同的条目。 因此,如果我们有两个相同的列表,并且我们修改了字典'a'中的键所指向的可变对象,则字典'b'中存在的字典对象也将看到这些更改。

可变数据类型的麻烦在于它们功能强大。 以上都不是真正的问题; 他们是牢记防止问题的事情。 在第三项中作为解决方案提出的昂贵的复制操作在99%的时间中都是不必要的。 您的程序可以而且应该进行修改,这样一开始甚至不需要这些副本。

编码愉快! 并随时在评论中提问。

翻译自:

python编码错误

转载地址:http://nwpzd.baihongyu.com/

你可能感兴趣的文章
小D课堂 - 新版本微服务springcloud+Docker教程_3-06 服务注册和发现之Eureka Client搭建商品服务实战...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_3-07 Eureka服务注册中心配置控制台问题处理...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_4-01 常用的服务间调用方式讲解
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_4-02 微服务调用方式之ribbon实战 订单调用商品服务...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_4-03 高级篇幅之Ribbon负载均衡源码分析实战...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_4-06 Feign核心源码解读和服务调用方式ribbon和Feign选择...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_4-05 微服务调用方式之feign 实战 订单调用商品服务...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_5-02 Netflix开源组件断路器
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_5-01分布式核心知识之熔断、降级
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_5-04 feign结合hystrix断路器开发实战下...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_5-03 feign结合hystrix断路器开发实战上...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_6-01 微服务网关介绍和使用场景
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_5-05熔断降级服务异常报警通知
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_6-03 高级篇幅之zuul常用问题分析
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_5-08 断路器监控仪表参数
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_6-02 springcloud网关组件zuul
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-1.快速搭建SpringBoot项目,采用Eclipse...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_1-4.在线教育后台数据库设计...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-3.热部署在Eclipse和IDE里面的使用...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_1-3.在线教育站点需求分析和架构设计...
查看>>