python中常见的错误(转)

在学习过程中,偶然发现一个博客,写的关于python中常见的10个错误,觉得比较不错,整理一下。

原文见:

http://bookshadow.com/weblog/2014/05/14/top-10-mistakes-that-python-programmers-make/

具体如下:

1:函数参数默认值表达式的误用

def fun(friut=[]):
    friut.append("apple")
    print friut

fun()    #['apple']
fun()    #['apple', 'apple']
fun()    #['apple', 'apple', 'apple']

        目的是调用fun(),想得到“apple”,但是当多次调用,发现产生的结果和期望中不一样。

原因是:函数的缺省值只在函数定义时进行一次初始化。fun()函数在第一次定义时初始化为缺省值,后续调用时,

会继续沿用最开始初始化得到的那个列表。

        解决如下:

def fun(friut=None):
    if friut is None:
        friut = []
    friut.append("apple")
    print friut

fun()    #['apple']
fun()    #['apple']
fun()    #['apple']

2:类变量的误用

        当子类没有独立于父类的属性时,对父类的属性进行的更改等相关操作。子类调用该属性时,也会发生变化,

其实子类调用该属性仅仅是对父类的引用。

class A(object):
    a = 1

class B(A):
    pass

class C(A):
    pass

print A.a, B.a, C.a    #1 1 1

B.a = 2
print A.a, B.a, C.a    #1 2 1

A.a = 5
print A.a, B.a, C.a    #5 2 5

3:异常块参数指定错误

        使用try,except时。捕捉多个异常错误时。应使用as关键词。

try:
    l = ["a", "b"]
    int(l[2])
except (ValueError, IndexError) as e:
    print 123

4:python作用域规则的误解

       python的作用域规则基于LEGB规则(local局部,enclosing封闭,global全局,build-in内置)

比如:变量定义在函数外,在函数内对变量进行操作。当其他模块调用该函数数,就会出现UnboundLocalError错误

num1 = 1
def fun():
    num1 += 1
    print num1

fun()    #UnboundLocalError: local variable 'num1' referenced before assignment

5:遍历列表时修改列表的值

在遍历时,不要从列表和数组中进行删除操作。在python中,可以使用列表解析来规避此问题。

num1 = lambda x: bool(x % 2)
numList = [i for i in range(10)]
for i in range(len(numList)):
    if num1(numList[i]):
        del numList[i]
print numList[:]    #IndexError

使用列表解析可以改为:

num1 = lambda x: bool(x % 2)
numList = [i for i in range(10)]
numList[:] = [i for i in numList if not num1(i)]
print numList    #[0, 2, 4, 6, 8]

6:python闭包绑定变量的误解

def creat_list():
    return [lambda x: i * x for i in range(5)]

for num1 in creat_list():
    print num1(2)    #8 8 8 8 8 

此程序的问题是因为python的延迟绑定行为导致的,就是说,任何一个返回的函数被调用时,i的值再起被调用时

在周围作用域查找,此时,循环已经完成。所以i一直都是4。

通过利用缺省参数生成匿名函数来获得期望的行为。

def creat_list():
    return [lambda x, i=i: i * x for i in range(5)]

for num1 in creat_list():
    print num1(2)    #0 2 4 6 8

7:创建循环模块依赖

主要是在导入时,要确定某些变量是否已经被定义过,否则会导致AttributeError 问题。

8:modules与python标准库模块的命名冲突

此问题是,不能将自己的模块命名为python的标准库,否则在import时,调用相关标准库函数是无法调用的。

9:忽略了python2和python3的区别

。。。多多积累吧。

10:__del__方法的误用

'''
mod.py
'''
import foo

class Bar(object):
   	    ...
    def __del__(self):
        foo.cleanup(self.myhandle)
'''
another_mod.py
'''
import mod
mybar = mod.Bar()    #AttributeError 

原因:当解释器关闭时,模块的全局变量全部设为None,就是当__del__被调用时,foo这个名字已经被设为None。

可以使用atexit.register()作为代替。

mod.py改为:(不是很理解。需深入学习。)

'''
mod.py
'''
import foo
import atexit

def cleanup(handle):
    foo.cleanup(handle)

class Bar(object):
   	    ...
    def __init__(self):
        atexit.register(cleanup, self.myhandle)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值