zoukankan      html  css  js  c++  java
  • Python学习笔记(三)

    一、文件和异常

    • 从文件中读取数据
      • 读取整个文件
    with open('10.txt') as file_object:         # 函数open()接受一个参数,即要打开的文件的名称;with在不再需要访问文件后将其关闭
        contents = file_object.read()           # 方法read()读取这个文件的全部内容,在到达文件末尾时返回一个空字符串(打印出来是个空行)
        print(contents)
      • 文件路径
    with open(text_filesfilename.txt) as file_object:       # 相对文件路径(打开的文件位于py文件文件夹的子文件夹中)
    

    file_path = 'C:UsersMayPython	ext_filesfilename.txt'
    with open(file_path) as file_object                      # 绝对文件路径(无需关心文件位于哪里)
      • 逐行读取
    filename = 'digits.txt'
    
    with open(filename) as file_object:
        for line in file_object:                         # file_object文件中每行末尾会有一个看不见的换行符
            print(line)
      • 创建一个包含文件各行内容的列表
    filename = 'digits.txt'
    
    with open(filename) as file_object:
        lines = file_object.readlines()       # 方法readlines()从文件中读取每一行
    
    for line in lines:
        print(line.rstrip())
      • 使用文件中的内容(若将字符串转换为数值使用,函数int()转换为整数,函数float()转换为浮点数)
    • 写入文件
      • 写入空文件
        • 写入模式'w'
        • 读取模式'r'
        • 附加模式'a'
        • 读取和写入模式'r+'
    filename = 'programming.txt'
    
    with open(filename, 'w') as f_obj:         # 第二个实参'w'告诉Python以写入模式打开文件,若文件不存在,则创建一个新文件;若存在,则覆盖原有内容
        f_obj.write("I love programming")
      • 附加到文件('a',将内容添加到文件末尾)
    • 异常(使用try-except代码块处理)
      • 处理ZeroDivisionError异常
    >>> print(5/0)
    Traceback (most recent call last):
      File "division.py", line 1, in <module>
        print(5/0)
    ZeroDivisionError: division by zero
      • 使用try-except代码块(返回一条友好信息而不是traceback)
    try:
        print(5/0)                            # 将导致错误的代码行放在一个try代码块中
    except ZeroDivisionError:                 # 若try代码块没问题,将跳过except代码块
        print("You can't divide by zero!")
      • 使用异常避免崩溃
      • else代码块(如果发生了指定的异常,该怎么做;若没发生,又该怎么做)
    print("Give me two numbers, and I'll divide them.")
    print("Enter 'q' to quit.")
    
    while True:
        first_number = input("
    First number: ")
        if first_number == 'q':
            break
        second_number = input("Second number: ")
        if second_number == 'q':
            break
        try:
            answer = int(first_number) / int(second_number)
        except ZeroDivisionError:
            print("You can't divide by zero!")
        else:
            print(answer)
      • 处理FileNotFoundError异常
    filename = 'alice.txt'
    
    with open(filename) as f_obj:
        contents = f_obj.read()
    
    Traceback (most recent call last):
      File "alice.py", line 3, in <module>
        with open(filename) as f_obj:
    FileNotFoundError: [Error 2] No such file or directory: 'alice.txt'
    filename = 'alice.txt'
    
    try:
        with open(filename) as f_obj:
            contents = f_obj.read()
    except FileNotFoundError:
        msg = "Sorry, the file " + filename + " does not exist."
        print(msg)
      • 分析文本(项目Gutenberg提供了一系列不受版权限制的文学作品)
    >>> title = "Alice in Wonderland"
    >>> title.split()            # 方法split()根据一个字符串创建一个单词列表,以空格为分隔符将字符串分拆
    ['Alice', 'in', 'Wonderland']
      • 使用多个文件
        • try-except代码块提供了两个优点:避免让用户看到traceback;让程序能够继续分析能够找到的其他文件
      • 失败时一声不吭
    try:
        --snip--
    except FileNotFoundError:
        pass                                # pass语句充当占位符
    else:
        --snip--
    • 存储数据(使用json模块)
      • JSON(JavaScript Object Notation)
      • 使用json.dump(),接受两个实参:要存储的是数据以及可用于存储数据的文件对象
    import json
    
    numbers = [2, 3, 5, 7, 11, 13]
    
    filename = 'numbers.json'              # 文件扩展名.json表示文件存储的数据为JSON格式
    with open(filename, 'w') as f_obj:
        json.dump(numbers, f_obj)          # 这个程序生成文件numbers.json,或覆盖文件原有内容,其数据的存储格式与Python一样
      • 使用json.load():将文件数据读取到内存中
    import json
    
    filename = 'numbers.json'
    with open(filename) as f_obj:
        numbers = json.load(f_obj)
    
    print(numbers)
      • 保存和读取用户生成的数据
    # remember_me.py

    import json
    
    # 如果以前存储了用户名,就加载它;否则,就提示用户输入用户名并存储它
    filename = 'username.json'
    try:
        with open(filename) as f_obj:
            username = json.load(f_obj)
    except FileNotFoundError:
        username = input("What is your name?")
        with open(filename, 'w') as f_obj:
            json.dump(username, f_obj)
            print("We'll remember you when you come bacck, " + username + "!")
    else:
        print("Welcome back, " + username + "!")
    • 重构:将代码划分为一系列完成具体工作的函数

     

    # 重构成一个函数
    import json
    
    def greet_user():
        """问候用户,并指出其名字"""
        filename = 'username.json'
        try:
            with open(filename) as f_obj:
                username = json.load(f_obj)
        except FileNotFoundError:
            username = input("What is your name? ")
            with open(filename, 'w') as f_obj:
                json.dump(username, f_obj)
                print("We'll remember you when you come back, " + username + "!")
        else:
            print("Welcome back, " + username + "!")
    
    greet_user()
    # 重构成两个函数
    import json
    
    def get_stored_username():
        """如果存储了用户名,就获取它"""
        filename = 'username.json'
        try:
            with open(filename) as f_obj:
                username = json.load(f_obj)
        except FileNotFoundError:
            return None
        else:
            return username
    
    def greet_user():
        """问候用户,并指出其名字"""
        username = get_stored_username()
        if username:
            print("Welcome back, " + username + "!")
        else:
            username = input("What is your name? ")
            filename = 'username.json'
            with open(filename, 'w') as f_obj:
                json.dump(username, f_obj)
                print("We'll remember you when you come back, " +username + "!")
    
    greet_user()
    # 重构成三个函数
    import json
    
    def get_stored_username():
        --snip--
    
    def get_new_username():
        """提示用户输入用户名"""
        username = input("What is your name? ")
        filename = 'useranme.json'
        with open(fileaname, 'w') as f_obj:
            json.dump(username, f_obj)
        return username
    
    def greet_user():
        """问候用户,并指出其名字"""
        username = get_stored_username()
        if username:
            print("Welcome back, " + username + "!")
        else:
            username = get_new_username()
            print("We'll remember you when you come back, " + username + "!")
    
    greet_user()

    二、测试代码

    • 测试函数:Python标准库中的模块unittest提供了代码测试工具
      1. 单元测试:用于核实函数的某个方面没有问题
      2. 测试用例:一组单元测试(全覆盖式测试用例)
    # name_function.py测试代码
    def get_formatted_name(first, last):
        """Generate a neatly formatted full name."""
        full_name = first + ' ' + last
        return full_name.title()
      • 可通过的测试
    # test_name_function.py
    import unittest
    from name_function import get_formatted_name
    
    class NamesTestCase(unittest.TestCase):                     # 该类用于包含一系列针对函数的单元测试,类名最好包含Test字样
        """测试name_function.py"""
        
        def test_first_last_name(self):                         # 运行py文件时,以test_开头的方法都将自动运行
            """能够正确处理像May Zheng这样的姓名吗?"""
            formatted_name = get_formatted_name('may', 'zheng')
            self.assertEqual(formatted_name, 'May Zheng')       # 一个断言方法
    
    if __name__ == '__main__':
        unittest.main()

    # 输出
    .                                                     # 句点表明有一个测试通过了
    -----------------------------------------
    Ran 1 test in 0.000s                                  # 运行了一个测试,消耗的时间不到0.001s
    
    OK                                                    # 测试用例中的所有单元测试都通过了
      • 不能通过的测试
    # 修改name_function.py如下
    def get_formatted_name(first, middle, last):
        """生成整洁的名字"""
        full_name = first + ' ' + middle + ' ' + last
        return full_name.title()
    # test_name_function.py
    import unittest
    from name_function import get_formatted_name
    
    class NamesTestCase(unittest.TestCase):                     # 该类用于包含一系列针对函数的单元测试,类名最好包含Test字样
        """测试name_function.py"""
        
        def test_first_last_name(self):                         # 运行py文件时,以test_开头的方法都将自动运行
            """能够正确处理像May Zheng这样的姓名吗?"""
            formatted_name = get_formatted_name('may', 'zheng')
            self.assertEqual(formatted_name, 'May Zheng')       # 一个断言方法
    
    if __name__ == '__main__':
        unittest.main()

    # 输出
    E                           # 指出测试用例中有一个单元测试导致了错误
    ==================================================================================
    ERROR: test_first_last_name (__main__,NamesTestCase)
    ----------------------------------------------------------------------------------
    Traceback (most recent call last):
      File "test_name_function.py", line 8, in test_first_last_name
        formatted_name = get_formatted_name('may', 'zheng')
    TypeError: get_formatted_name() missing 1 required positional argument: 'last'
    ----------------------------------------------------------------------------------
    Ran 1 test in 0.000s
    
    FAILED (errors=1)
      • 测试未通过时:应修改导致测试不能通过的代码,而不是修改测试
    # 修改name_function.py如下
    def get_formatted_name(first, last, middle=''):
        """生成整洁的名字"""
        if middle:
            full_name = first + ' ' + middle + ' ' + last
        else:
            full_name = first + ' ' + last
        return full_name.title()
      • 添加新测试(用于测试包含中间名的姓名)
    # test_name_function.py
    import unittest
    from name_function import get_formatted_name
    
    class NamesTestCase(unittest.TestCase):                     # 该类用于包含一系列针对函数的单元测试,类名最好包含Test字样
        """测试name_function.py"""
        
        def test_first_last_name(self):                         # 运行py文件时,以test_开头的方法都将自动运行
            """能够正确处理像May Zheng这样的姓名吗?"""
            formatted_name = get_formatted_name('may', 'zheng')
            self.assertEqual(formatted_name, 'May Zheng')       # 一个断言方法
    
        def test_first_last_middle_name(self):
            """能够正确处理像May Yi Zheng这样的姓名吗?"""
            formatted_name = get_formatted_name(
                    'may', 'zheng', 'yi')
            self.assertEqual(formatted_name, 'May Yi Zheng')
    
    if __name__ == '__main__':
        unittest.main() 
    # 输出
    ..
    -----------------------------------------------------------------------
    Ran 2 tests in 0.000s
    
    OK   
    •  测试类
      • 各种断言方法(Python在unittest.TestCase类中提供了很多断言方法,断言方法检查你认为应该满足的条件是否满足)
    unittest Module中的断言方法
    方法 用途
    assertEqual(a,b) 核实a == b
    assertNotEqual(a,b) 核实a != b
    assertTrue(x) 核实x为True
    assertFalse(x) 核实x为False
    assertIn(item, list) 核实itemlist
    assertNotIn(item, list) 核实item不在list
      • 要测试类的行为,需要创建其实例
    # 一个要测试的类,survey.py
    class AnonymousSurvey():
        """收集匿名调查问卷的答案"""
    
        def __init__(self, question):
            """存储一个问题,并为存储答案做准备"""
            self.question = question
            self.responses = []
    
        def show_question(self):
            """显示调查问卷"""
            print(self.question)
    
        def store_response(self, new_response):
            """存储单份调查问卷"""
            self.responses.append(new_response)
    
        def show_results(self):
            """显示收集到的所有答卷"""
            print("Survey results:")
            for response in self.responses:
                print('- ' + response)
    # 测试AnonynousSurvey类,test_survey.py
    import unittest
    from survey import AnonymousSurvey
    
    class TestAnonymousSurvey(unittest.TestCase):
        """针对AnonymousSurvey类的测试"""
    
        def test_store_single_response(self):
            """测试单个答案会被妥善地存储"""
            question = "What language did you first learn to speak?"
            my_survey = AnonymousSurvey(question)
            my_survey.store_response('English')
    
            self.assertIn('English', my_survey.responses)
    
        def test_store_three_responses(self):
            """测试三个答案会被妥善地存储"""
            question = "What language did you first learn to speak?"
            my_survey = AnonymousSurvey(question)
            responses = ['English', 'Spanish', 'Mandarin']
            for response in responses:
                my_survey.store_response(response)
    
            for response in responses:
                self.assertIn(response, my_survey.responses)
    
    if __name__ == '__main__':
        unittest.main()
      • 方法setUp():先运行setUp()方法,再运行以test_开头的方法(上述测试类额代码可以不用在每个方法中创建实例)
    import unittest
    from survey import AnonymousSurvey
    
    class TestAnonymousSurvey(unittest.TestCase):
        """针对AnonymousSurvey类的测试"""
    
        def setUp(self):                 # 在setUp()方法中创建一系列实例并设置它们的属性,再在测试方法中直接使用这些实例
            """
            创建一个调查对象和一组答案,供使用的测试方法使用
            """
            question = "What language did you first learn to speak?"
            self.my_survey = AnonymousSurvey(question)
            self.responses = ['English', 'Spanish', 'Mandarin']
    
        def test_store_single_response(self):
            """测试单个答案会被妥善地存储"""
            self.my_survey.store_response(self.responses[0])
            self.assertIn(self.responses[0], self.my_survey.responses)
    
        def test_store_three_responses(self):
            """测试三个答案会被妥善地存储"""
            for response in self.responses:
                self.my_survey.store_response(response)
            for response in self.responses:
                self.assertIn(response, self.my_survey.responses)
    
    if __name__ == '__main__':
        unittest.main()
      • 每完成一个单元测试,Python都打印一个字符:
        • 测试通过时:打印一个句点
        • 测试引发错误时:打印一个E
        • 测试导致断言失败时:打印一个F
  • 相关阅读:
    大聊Python----SocketServer
    2、MySQL常见数据库引擎及比较?
    大聊Python----通过Socket实现简单的ssh客户端
    1、列举常见的关系型数据库和非关系型都有那些?
    uva12563 Jin Ge Jin Qu hao(01背包)
    UVA 12174 Shuffle(滑动窗口)
    C++中substr函数的用法
    uva11078
    11462 Age Sort(计数排序)
    UVA 11988 Broken Keyboard (a.k.a. Beiju Text) (链表,模拟)
  • 原文地址:https://www.cnblogs.com/mayyzym/p/10314837.html
Copyright © 2011-2022 走看看