Day 3 笔记

146 阅读7分钟

一· 类

  • 根据约定,首字母大写的名称指的是类。

    class Dog(): 
    """一次模拟小狗的简单尝试""" #文档字符串,对这个类的功能作了描述。
    
  1. 方法 (唯一区别于函数的是调用方法)

     *  __init__()
     开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。
    
     *  def _init_(self,name,age)
    我们将方法__init__() 定义成了包含三个形参:self 、name 和age 。形参self 必不可少,还必须位于
    其他形参的前面。因为Python调用这个__init__() 方法来创建Dog 实例时,将自动传入实参self 。每个与
    类相关联的方法调用都自动传递实参self ,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
    我们将通过实参向Dog() 传递名字和年龄;self 会自动传递。
    
  2. 属性(通过实例访问的变量)

    *  self.name = name
       self.age = age
    以self为前缀的变量都可供类中的所有方法使用,我们还可以通过类的任何实例来
    访问这些变量。self.name = name 获取存储在形参name 中的值,并将其存储到变量name 中,然后该变量被
    关联到当前创建的实例。
    

3.实例

    *  class Dog():
       my_dog = Dog('willie', 6)
       print( my_dog.name.title() ) 
    使用Dog 类,创建一条名字为'willie' 、年龄为6 的小狗。Python使用实参'willie' 和6 调用Dog 类
    中的方法__init__() 。方法__init__() 创建一个表示特定小狗的示例,并使用我们提供的值来设置属性
    name 和age 。实例存储在变量my_dog 中。我们通常可以认为首字母大写的名称(如Dog )指的是类,而
    小写的名称(如my_dog )指的是根据类创建的实例。
    
    * class Dog(): 
      """一次模拟小狗的简单尝试"""
      def __init__(self, name, age):
      """初始化属性name和age""" 
      self.name = name
      self.age = age
      def sit(self):
      """模拟小狗被命令时蹲下"""
      print(self.name.title() + " is now sitting.")
      def roll_over(self):
      """模拟小狗被命令时打滚"""
      print(self.name.title() + " rolled over!")
   
     class Dog():
     my_dog = Dog('willie', 6)
     your_dog = Dog('lucy', 3)
     my_dog.sit()
     your_dog.sit()

4.修改属性的值

*直接修改属性的值
 通过实例直接访问它
 my_new_car.odometer_reading = 23
 
 *通过方法修改属性的值
 def update_odometer(self, mileage):
 """将里程表读数设置为指定的值"""
 self.odometer_reading = mileage
 my_new_car.update_odometer(23)
 
 *通过方法对属性的值进行递增
 def increment_odometer(self, miles):
 """将里程表读数增加指定的量"""
 self.odometer_reading += miles

5.继承

  • 继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法

  • 给父类的所有属性赋值。

  • 创建子类时,父类必须包含在当前文件中,且位于子类前面

  • super() 是一个特殊函数,帮助Python将父类和子类关联起来。

    class Car():
    ......
    class ElectricCar(Car):
    """电动汽车的独特之处"""
    def __init__(self, make, model, year):
    """初始化父类的属性""" 
    super().__init__(make, model, year)
    """联接父类与子类"""
    my_tesla = ElectricCar('tesla', 'model s', 2016)
    print(my_tesla.get_descriptive_name())
    
  • 重写父类的方法

    假设Car 类有一个名为fill_gas_tank() 的方法,你可能想重写它。

    def ElectricCar(Car):
    --snip--
    def fill_gas_tank():
    """电动汽车没有油箱"""
    print("This car doesn't need a gas tank!")
    

    如果有人对电动汽车调用方法fill_gas_tank() ,Python将忽略Car 类中的方法fill_gas_tank() ,转而运行上述代码

  • 将实例用作属性

    当子类中需要添加的细节太多,可将这些属性和方法提取出来,放到另一个名 为Battery 的类中,并将一个Battery 实例用作ElectricCar 类的一个属性:

    class Car():
    --snip--
    class Battery():
    """一次模拟电动汽车电瓶的简单尝试"""
         def __init__(self, battery_size=70):
         """初始化电瓶的属性"""
         self.battery_size = battery_size
         def describe_battery(self):
         """打印一条描述电瓶容量的消息"""
         print("This car has a " + str(self.battery_size) + "-kWh battery.")
    class ElectricCar(Car):
    """电动汽车的独特之处"""
         def __init__(self, make, model, year):
         """ 初始化父类的属性,再初始化电动汽车特有的属性"""
         super().__init__(make, model, year) 
         self.battery = Battery() #将实例储存在属性中
         my_tesla = ElectricCar('tesla', 'model s', 2016)
         print(my_tesla.get_descriptive_name())
         my_tesla.battery.describe_battery() 
         #在实例my_tesla中查找属性battery,并从属性中调用方法describe_battery()
    
  • 导入类(简化此文件代码)

    from car import Car  #一个类
    打开模块car,并导入其中的Car类
    
    from car import Car, ElectricCar  #多个类
    
  • 类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。实例名和模块名都采用小写格式,并在单词之间加上下划线

二·文件

1.读取文件

  with open('pi_digits.txt') as file_object:
  contents = file_object.read()
  print(contents)
  #关键字with 在不再需要访问文件后将其关闭
  #函数open()接受一个参数:要打开的文件的名称。
  #使用方法read()读取这个文件的全部内容存储在变量contents 中
       方法readlines() 从文件中读取每一行作为一个元素,并将其存储在一个列表中
  #区别于原文件,read()到达文件末尾会返回一个空字符串,
  输出末尾多了一个空行,l可用rstrip()删除

2.文件路径

  • 相对文件路径(同在python_work文件夹,处于平行关系的情况)

    with open('text_files\filename.txt') as file_object
    Python到文件夹python_work下的文件夹text_files中去查找指定的.txt文件
    
  • 绝对文件路径(文件在计算机中的准确位置)

    file_path = 'C:\Users\ehmatthes\other_files\text_files\filename.txt'
     with open(file_path) as file_object:
    #因为路径很长,将其储存在一个变量
    

tips:print 语句自动会加上空行符

可使用方法replace() 将字符串中的特定单词都替换为另一个单词

  >>> message = "I really like dogs."
  >>> message.replace('dog', 'cat')
  'I really like cats.'

3.写入文件

  • 读取模式 ('r' )、写入模式 ('w' )、附加模式 ('a' )、能够读取和写入文件的模式('r+' )

  • 要写入的文件不存在,函数open() 将自动创建它。 然而,以写入('w' )模式打开文件时千万要小心,因为如果指定的文件已经存在,Python将在返回文件对象前清空 该文件

    filename = 'programming.txt'
    with open(filename, 'w') as file_object: 
    file_object.write("I love programming.")
    #方法write() 将一个字符串写入文件,注意换行符
    
  • Python只能将字符串写入文本文件。要将数值数据存储到文本文件中,必须先使用函数str() 将其转换为字符串格式。

4.处理异常

处理ZeroDivisionError 异常(无法按照你的代码要求执行时)

处理FileNotFoundError 异常(找不到文件)

  • try-except 代码块(若让程序异常时不告诉用户,则在except中引用pass语句什么都不做)

    try:
        print(5/0)
    except ZeroDivisionError:
        print("You can't divide by zero!")
    
  • else 代码块

     try:
        answer = int(first_number) / int(second_number) 
     except ZeroDivisionError:
         print("You can't divide by 0!") 
     else:
         print(answer)
    

5.分析文本

  • 计算一个文本包含多少个单词

    方法split()以空格为分隔符将字符串分拆成多个部分,根据一个字符串创建一个单词列表 len()得到单词个数

  • 使用多个文件(利用for)

    将代码移到函数count_words()中
    def count_words(filename):
    --snip--
    filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
    for filename in filenames:
    count_words(filename)
    
  • 存储数据

    json.dump()#写入 和json.load()#读取加载

6.重构将代码划分为一系列完成具体工作的函数, 让代码更清晰、更易于理 解、更容易扩展。

三、测试

 单元测试 用于核实函数的某个方面没有问题;
 测试用例 是一组单元测试,这些单元测试一起核实函数在各种情形下的
 行为都符合要求。
  • 编写测试用例

    要为函数编写测试用例,可先导入模块unittest 以及要测试的函
    数,再创建一个继承unittest.TestCase 的类,并编写一系列方法对函数行为的不同方面进行测试
    
    import unittest
    from name_function import get_formatted_name
    class NamesTestCase(unittest.TestCase):
        """测试name_function.py"""
        def test_first_last_name(self):
        """能够正确地处理像Janis Joplin这样的姓名吗?""" 
            formatted_name = get_formatted_name('janis', 'joplin') 
            self.assertEqual(formatted_name, 'Janis Joplin') #断言(判断q变量与预期字符串结果是否相同)
    unittest.main() #运行测试
    

    方法名必须以test_打头,这样它才会在我们运行test_name_function.py时自动运行

    四、断言方法

    unittest Module中的断言方法

     * assertEqual(a, b) 核实a == b
     * assertNotEqual(a, b) 核实a != b
     * assertTrue(x) 核实x 为True
     * assertFalse(x) 核实x 为False
     * assertIn(item , list ) 核实 item 在 list 中
     * assertNotIn(item , list ) 核实 item 不在 list 中
    
  • 方法assertIn(x,list) 来核实它包含在答案列表中

  • 方法setUp() 来创建一个调查对象和一组答案

    你在TestCase 类中包含了方法setUp(),Python将先运行它,再运行各个以test_打头的方法
    def setUp(self):
     """ 创建一个调查对象和一组答案,供使用的测试方法使用 """
     question = "What language did you first learn to speak?" 
     self.my_survey = AnonymousSurvey(question) 
     self.responses = ['English', 'Spanish', 'Mandarin']