python脚本错误总结

纪录自己在写脚本过程中遇到的一些错误,方便后续查看。

1、文件名与模块中的函数名相同导致

import multiprocessing
import os,time

def inputQ(queue):
    info = str(os.getpid()) + '(put):' + str(time.time())
    queue.put(info)

def outputQ(queue,lock):
    if not queue.empty():
        info = queue.get()
        lock.acquire()
        print((str(os.getpid()) + '(get):' + info))
        lock.release()

if __name__ == '__main__':

    record1 = []
    record2 = []
    lock = multiprocessing.Lock()
    queue = multiprocessing.Queue()

    for i in range(10):
        process = multiprocessing.Process(target=inputQ,args=(queue,))
        process.start()
        record1.append(process)

    for i in range(10):
        process = multiprocessing.Process(target=outputQ,args=(queue,lock))
        process.start()
        record2.append(process)

    for p in record1:
        p.join()

    queue.close()

    for p in record2:
        p.join()

运行后错误提示如下:

from queue import Empty, Full
ImportError: cannot import name 'Empty'

这里写图片描述
这个问题比较隐蔽,提示from queue import Empty, Full,还专门看了源码,以为没有empty和full两个类,结果看了以后是有的,并且代码在python2.7的环境下可以正常运行,我目前使用的是python3.5版本,报这个错误,一度怀疑是不是python3和python2的区别导致的这个错误,最后尝试把代码文件名queue.py改成了queue01.py才解决该问题,所以文件命名时一定要注意。。。

2、变量名与函数名相同导致

使用ipython调试脚本时,一直报如下错误,代码很简单,最后发现之前调试时,有变量名字为str,与string模块中的str函数重名,所以报如下错误,所以再给变量命名时,应注意。

>>> random_gen_cid()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "<console>", line 2, in random_gen_cid
TypeError: 'str' object is not callable

3、未安装相应的模块

在使用configobj 模块时,提示:

>>> from configobj import ConfigObj
Traceback (most recent call last):
  File "<console>", line 1, in <module>
ImportError: No module named configobj

由于没有安装configobj 模块,在终端使用pip install configobj安装即可。

这里写图片描述

这里写图片描述

4、KeyError报错

提示如下:

Traceback (most recent call last):
  File "<console>", line 3, in <module>
  File "C:\Python27\lib\site-packages\configobj.py", line 554, in __getitem__
    val = dict.__getitem__(self, key)
KeyError: 'read_interface'

字典中没有关键字’read_interface’,我在代码中使用了config1 = ConfigObj(tel_conf),打印config1 ,发现config1为空的元祖,检查发现,tel_conf的路径写错了,导致为空,config1中无关键字’read_interface’。

5、缩进异常

错误提示:

>>>   dict = {'Name': 'Zara', 'Age': 7};
  File "<console>", line 1
    dict = {'Name': 'Zara', 'Age': 7};
    ^
IndentationError: unexpected indent

提示缩进异常,调整缩进即可。

>>> dict = {'Name': 'Zara', 'Age': 7};
>>> 

6、导入模块错误

>>> from common import *
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File ".\common.py", line 11
SyntaxError: Non-ASCII character '\xe9' in file .\common.py on line 11, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
>>> 

一直以为python模块中有个模块common,还尝试安装common模块,结果安装不成功,百度结果都是说需要设置字符编码#coding=utf-8,但是不起作用,真是对自己无语了,当前目录下,有同事写的common.py文件,from common import *,就是直接导入了当前目录下的common模块,因为调试的时候,用的ipython调试,直接执行from common import *,所以导致上述错误。
需明白,导入模块时,python首先查找当前目录下的模块。

7、用ipython调试时,比如很简单的一段代码:

>>> s = 0
>>> for i in range(11):
...     s = s + i
... print s
  File "<console>", line 3
    print s
        ^
SyntaxError: invalid syntax

这里写图片描述

一直提示语法错误SyntaxError: invalid syntax,搞了好久,才发现ipython调试代码时,循环语句写完以后,要多敲一个回车,退出循环,才能接着写下面的语句;修改后正常。

这里写图片描述

8、递归函数栈溢出

>>> def func(n):
...     if n==1:
...         return 1
...     else:
...         return n*func(n-1)
... 
>>> func(100)
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000L
>>> func(1000)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "<console>", line 5, in func
  .
  .
  .
  File "<console>", line 5, in func
RuntimeError: maximum recursion depth exceeded

使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。

尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

上面的fact(n)函数由于return n * fact(n - 1)引入了乘法表达式,所以就不是尾递归了。要改成尾递归方式,需要多一点代码,主要是要把每一步的乘积传入到递归函数中:

>>> def fact_iter(num, product):
    if num == 1:
        return product
    return fact_iter(num - 1, num * product)
... ... ... ... 
>>> def fact(n):
    return fact_iter(n, 1)

... ... >>> 
>>> fact(5)
120
>>> fact(1000)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "<console>", line 2, in fact
  File "<console>", line 4, in fact_iter
RuntimeError: maximum recursion depth exceeded

可以看到,return fact_iter(num - 1, num * product)仅返回递归函数本身,num - 1num * product在函数调用前就会被计算,不影响函数调用。

尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。

遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出。
Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。

9、
报错信息:IndentationError: expected an indented block

"base.py" 52L, 1451C written                                                                                                                                                                                              
[root@test30s4 library]# ./base.py  
  File "./base.py", line 53

    ^
IndentationError: expected an indented block

很奇怪,我的base.py文件总共才49行,查看base.py文件,发现if __name__ == '__main__':中,刚才把左右的都给注释了,如下:

if __name__ == '__main__':
    #remote_rpc("http://xxxxx.com")
    #remote_rpc("http://xxxxx.com")

任意去掉一个#即可。

10、IndentationError: unindent does not match any outer indentation level

  File "mysql_opera.py", line 26
    def getValue(self,data):
                           ^
IndentationError: unindent does not match any outer indentation level

查看了26行,并没有错误,该行就是定义了一个函数,使用的vim编译器,有时候用的table键空格,有时候用的空格键,于是将所有的缩进全部替换成tab键,重新运行脚本ok!

11、UnboundLocalError: local variable ‘data’ referenced before assignment

(1054, "Unknown column '7nJKEFX9' in 'where clause'")
Traceback (most recent call last):
  File "StreamManager.py", line 43, in <module>
    test.assertCreateStream()
  File "StreamManager.py", line 25, in assertCreateStream
    data1 = self.mysql.executeMysql(sql1)
  File "/usr/local/sandai/zhang_tools/xcloud_tool/auto_test/stream_Manager_auto/library/mysql_opera.py", line 24, in executeMysql
    return data
UnboundLocalError: local variable 'data' referenced before assignment

出问题代码:

                cur = conn.cursor()
                print("connect success!")
                try:
                        cur.execute(sql)
                        data = cur.fetchone()
                        print("select data:", data)
                except Exception, e:
                        print e
                cur.close()
                conn.commit()
                conn.close()
                return data

data的范围在try函数中,导致提示此错误,修改代码为:

                cur = conn.cursor()
                print("connect success!")
                try:
                        cur.execute(sql)
                        data = cur.fetchone()
                        print("select data:", data)
                        cur.close()
                        conn.commit()
                        conn.close()
                        return data
                except Exception, e:
                        print e

即可。

12:SyntaxError: non-default argument follows default argument

# python basic_stream_opera.py
  File "basic_stream_opera.py", line 24
    def createStream(self, businessID, streamKey, streamName='autotest', streamType='rtmp', pullUrl):
SyntaxError: non-default argument follows default argument

如果一个函数的参数中含有默认参数,则这个默认参数后的所有参数都必须是默认参数 ,
否则会抛出:SyntaxError: non-default argument follows default argument的异常,将此处pullurl添加一个默认参数即可!

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猜不透987872674

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值