python基础

本文围绕Python展开,介绍了异常处理机制,包括错误捕获、使用else、调用栈、logging模块和raise语句;阐述了调试方法,如print、assert、logging、pdb和IDE;讲解了单元测试,使用unittest模块;还探讨了引号问题,如单双引号及三个引号的使用,以及IO问题。

异常处理

处理机制

python异常处理机制:

try:
    ...
except:
    ...
finally:
    ...

except可以有多个,根据try块中的异常类型执行不同的except处理,不管有无异常,finally中的代码都会执行。

错误捕获

Python的错误也是class,所有的错误类型都继承BaseException,如果前一个except的错误时下一个except错误的父类,则子类错误中的代码块不执行,如:

try:
    ....
except ValueError as e:
    print('ValueError')
except UnicodeError as e:
    print('UnicodeError')

因为UnicodeError是ValueError的子类,故永远不会执行

print('UnicodeError')

使用else

如果没有捕获到相关错误,又需要打印一个log,或需要其他处理,可以使用else,如:

try:
    print('try...')
    r=10/2
    print('result:',r)
except ZeroDivisionError as e:
    print('except',e)
else:
    print('No error...')
finally:
    print('finally...')
print('END')

调用栈

python抛出的异常与Java类似,若没有被捕获到,会一层一层往上抛,最后被python解释器捕获,Java中的异常如果一直没有被捕获,会抛到main函数中

logging模块

python中的logging模块是用来记录错误信息的,打印出错误类型后,还会将错误信息记录到日志中,方便排查,如:

#logging.py
import logging
try:
    print('try...')
    r=10/0
    print('result:',r)
except ZeroDivisionError as e:
    logging.exception(e)
else:
    print('else ...')
finally:
    print('finally...')
print('END')

使用raise

raise语句将错误抛出去,给上一层处理,如:

#logging.py
import logging

try:
    print('try...')
    r=10/0
    print('result:',r)
except ZeroDivisionError as e:
    logging.exception(e)
    raise
else:
    print('else ...')
finally:
    print('finally...')
print('END')

调试

调试的方法有:使用print打印,assert,logging,pdb,IDE
print 将错误信息打印
assert 用print查看的地方都可以用assert,其形式为:

assert 表达式,打印的错误信息

若表达式为true,则没有错误,若为false则打印错误信息
若断言失败,assert语句则抛出AssertionError
logging 将错误打印并记录到文件
pdb可以使用python -m pdb 文件名.py来调试代码,可以单步执行,使用n进入下一步(next),也可以使用断点执行,使用c进入下一个断点(continue)
文件test.py内容为:

# err.py
s = '0'
n = int(s)
print(10 / n)

单步调试
执行:python - m pdb test.py
调试如下


C:\PythonCode>python -m pdb test.py
> c:\pythoncode\test.py(2)<module>()
-> s='0'
(Pdb) n
> c:\pythoncode\test.py(3)<module>()
-> n=int(s)
(Pdb) n
> c:\pythoncode\test.py(4)<module>()
-> print(10/n)
(Pdb) n
ZeroDivisionError: division by zero
> c:\pythoncode\test.py(4)<module>()
-> print(10/n)

断点调试:
先在代码中加入断点:pdb.set_trace()
文件如:

#error.py
s='0'
n=int(s)
pdb.set_trace()
print(10/n)

调试结果:

C:\PythonCode>python -m pdb test.py
> c:\pythoncode\test.py(2)<module>()
-> s='0'
(Pdb) c
Traceback (most recent call last):
  File "C:\applications\Python\Python36\lib\pdb.py", line 1667, in main
    pdb._runscript(mainpyfile)
  File "C:\applications\Python\Python36\lib\pdb.py", line 1548, in _runscript
    self.run(statement)
  File "C:\applications\Python\Python36\lib\bdb.py", line 434, in run
    exec(cmd, globals, locals)
  File "<string>", line 1, in <module>
  File "c:\pythoncode\test.py", line 2, in <module>
    s='0'
NameError: name 'pdb' is not defined
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> c:\pythoncode\test.py(2)<module>()
-> s='0'
(Pdb)

IDE
使用PyCharm,VS Code调试

单元测试

对于单元测试,Python自带unittest模块
测试类中,默认以test开头的方法就是测试方法,如test_Method, 不以test开头的方法是不会被执行的
assertEqual:判断输出的是否与我们期望的相等,如:

self.assertEqual(3-2, 1)  #判断3-2是否等于1 

assertTrue 判断条件是否成立
assertRaises 期待抛出指定类型的Error,如:

#通过d.empty访问不存在的key时,我们期待抛出AttributeError
with self.assertRaises(AttributeError):
    value = d.empty

**测试实例 **
student.py如下:

import unittest

class Student(object):
    def __init__(self,name,score):
        self.name=name
        self.score=score

    def get_grade(self):
        if self.score>100 or self.score<0:
            raise ValueError
        if self.score>=60 and self.score<80:
            print('name:',self.name,'******score:',self.score)
            return 'B'
        if self.score>=80:
            print('name:',self.name,'******score:',self.score)
            return 'A'
        print('name:',self.name,'******score:',self.score)
        return 'C'

testStudent.py如下:

from student import Student
import unittest
class TestStudent(unittest.TestCase):
    def test_80_to_100(self):
        print('test_80_to_100')
        s1=Student('Bart',80)
        s2=Student('Lisa',100)
        print('s1成绩',s1.get_grade())
        self.assertEqual(s1.get_grade(),'A')
        print('s2成绩',s2.get_grade())
        self.assertEqual(s2.get_grade(),'A')

    def test_60_to_80(self):
        print('test_60_to_80')
        s1=Student('Bart',69)
        s2=Student('Lisa',79)
        self.assertEqual(s1.get_grade(), 'B')
        self.assertEqual(s2.get_grade(), 'B')

    def test_0_to_60(self):
        print('test_0_to_60')
        s1 = Student('Bart', 0)
        s2 = Student('Lisa', 59)
        self.assertEqual(s1.get_grade(), 'C')
        self.assertEqual(s2.get_grade(), 'C')

    def test_invalid(self):
        print('test_invalid')
        s1 = Student('Bart', -1)
        s2 = Student('Lisa', 101)
        with self.assertRaises(ValueError):
            s1.get_grade()
        with self.assertRaises(ValueError):
            s2.get_grade()

if __name__ == '__main__':
    unittest.main()

输出结果:

test_0_to_60
name: Bart ******score: 0
name: Lisa ******score: 59
.test_60_to_80
name: Bart ******score: 69
name: Lisa ******score: 79
.test_80_to_100
name: Bart ******score: 80
s1成绩 A
name: Bart ******score: 80
name: Lisa ******score: 100
s2成绩 A
name: Lisa ******score: 100
.test_invalid
.
----------------------------------------------------------------------
Ran 4 tests in 0.227s

OK
>>> 

引号问题

单引号,双引号

单引号和双引号都可以标识字符串,如:

str='python'
strCopy="python"

str和strCopy输出都是python
如果用单引号标识字符串,字符串包含单引号,就必须用转义字符\ ,如:

str='I\'m python'

打印结果:

I'm python

如字符串含多个单引号,看起来特别费劲,因此python为了支持单引号与双引号
若用双引号表示字符串,则字符串里面的单引号为普通字符,不需要转义
若用单引号表示字符串,则字符串里面的双引号为普通字符,不需要转义

如:

str="I'm python, and PHP is the best language,isn't it???"
print(str)

输出

I'm python, and PHP is the best language,isn't it???
>>> 

3个单引号与3个双引号

当字符串很长,需要写多行,且要单行打印时,可考虑使用3个单引号或3个双引号
字符串有单引号即可用双引号定义字符串,反之用单引号定义字符串
如:

str="I am python\
He is C++\
She is PHP"
print(str)

输出:

I am pythonHe is C++She is PHP
>>> 

使用3个双引号

str="""I am python
He is C++
She is PHP
"""
print(str)

输出:

I am python
He is C++
She is PHP

使用3个引号得另一个作用:可直接添加注释,如:

str="""I am python  #python大法好
He is C++   #我比你们快
She is PHP  #呵呵,PHP才是最好的语言
"""
print(str)

输出:

I am python  #python大法好
He is C++   #我比你们快
She is PHP  #呵呵,PHP才是最好的语言

>>> 

IO问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值