美文网首页
Python基础

Python基础

作者: 西电大侠 | 来源:发表于2020-09-16 17:42 被阅读0次

    第二章 变量和简单数据类型

    运行py文件时发生的情况
    运行hello_world.py文件时,末尾的.py指出这是一个Python程序,因此编辑器将使用Python解释器来运行它。Python解释器读取整个程序,确定每个单词的含义。例如print,解释器就将括号里的内容打印到屏幕上。

    变量名只能包含字母、数字和下划线,不能以数字开头,而且应该全部小写。

    字符串拼接
    first_name = 'ada'
    last_name = 'lovelace'
    full_name = first_name + " " + full_name

    使用制表符或换行符来添加空白
    print("Languages:\n\tPython\n\tJavaScript")

    删除空白
    favorite_language = 'python '
    favorite_language.rstrip()
    strip()和lstrip()是删除开头的空格
    rstrip()是删除结尾的空格

    第三章 列表

    列表简介
    bicycles = ['trek', 'cannondale', 'redline', 'specialized']
    列表是有序集合,因此要访问列表的任何元素,只需要将元素的位置或者索引告诉Python即可。
    索引是从0开始
    索引的最后一个是-1,倒数第二个是-2,以此类推。
    修改列表元素
    motocycles = ['honda', 'yamaha', 'suzuki']
    mococycles[0]='ducati'

    添加元素
    1、在末尾添加
    motocycles = [] #先创建空的列表
    motocycles.append('ducati')

    2、在列表中插入元素
    motocycles = ['honda', 'yamaha', 'suzuki']
    motocycles.insert(1, 'ducati')
    方法insert()在索引1处添加空间,并将值'ducati'存储到这个地方。这种操作将列表中排序1之后的每个元素都右移一个位置。

    3、从列表中删除元素
    motocycles = ['honda', 'yamaha', 'suzuki']
    del motocycles[0]

    pop删除
    motocycles.pop()
    弹出列表最后一个元素
    弹出特定位置元素
    motocycles.pop(1) #弹出第二个元素
    被弹出的元素可以继续复制使用
    比如first_owned = motocycles.pop(0)
    虽然列表中没有该元素,但是该元素值可以继续使用

    4、根据值删除元素
    motocycles = ['honda', 'yamaha', 'suzuki']
    motocycles.remove('honda')

    组织列表
    sort()对列表进行永久排序
    sort(reverse=True)倒序排序

    sorted()对列表进行临时排序,原来的列表的顺序并没有变

    reverse()反转列表,这里的反转是指元素的排列顺序反转

    len()确定列表的长度

    第四章 操作列表

    遍历列表list
    motocycles = ['honda', 'yamaha', 'suzuki']
    for moto in motocycles:
    print(moto)

    创建数字列表
    使用函数range(),range()让你能够生成一系列的数字。
    for value in range(1,5):
    print(value)
    打印不包括5

    要创建数字列表,可以使用函数list()将range()的结果直接转换为列表。
    numbers = list(range(1,5))
    print(numbers)

    [1,2,3,4]

    range()还可以指定步长,如range(2,11,2),从2开始,不断的加2,直到11(不包括11)

    数字列表的简单计算
    min(numbers)
    max(numbers)
    sum(numbers)

    使用列表的一部分
    切片
    列表的部分元素-Python称之为切片
    players = ['charles', 'martina', 'michael, 'florence', 'eli']
    提取第2-4个元素。
    players[1:4]
    如果没有指定第一个索引,那就是从开头开始
    players[:4]
    如果没有指定第二个索引,那就直接到末尾
    players[2:]
    负数索引能够让你输出特定位置到列表末尾的所有元素
    players[-2:]
    将输出-1,-2两个元素

    遍历切片
    for player in players[1:3]:
    print player

    复制列表
    假如我喜欢的食物,有一个朋友也喜欢,然后我喜欢的列表多了一样,朋友喜欢的也多了一样。
    刚开始三样一样,如何复制列表?
    my_foods =['pizza', 'falafel', 'carrot cake']
    friend_foods = my_foods

    my_foods.append('cannoli')
    friend_foods.append('ice cream')

    print(my_foods)
    print(friend_foods)
    你会发现,这两个列表输出的一模一样,而且cannoli和ice cream都在列表里面。为什么呢,因为friend_foods = my_foods并没有复制列表,而只是新建了一个friend_foods变量,关联到原来的my_foods上。所以,改动其实是在一个列表上。
    那如何正确复制?利用切片。
    my_foods =['pizza', 'falafel', 'carrot cake']
    friend_foods = my_foods[:]

    my_foods.append('cannoli')
    friend_foods.append('ice cream')

    print(my_foods)
    print(friend_foods)

    元组tuple
    列表可以动态调整,使得满足各种需求,如果你有不变的列表,那这样的列表可以被称为元组。

    定义元组
    元组看起来和列表类似,区别在于元组是圆括号,列表是方括号。

    dimensions = (200, 50)
    dimensions[0] = 250
    这里复制会报错,因为tuple不能被改变

    遍历元组
    for dimension in dimensions:
    print(dimension)
    虽然不能更改单个元组某个元素的值,但是可以更改整个元组的值。
    dimensions = (200, 50)
    dimensions = (400, 100)
    这里并不会报错。

    第五章 if语句

    判断相等 ==
    判断不等 !=
    检查特定值是否包含在列表中
    request_topping=['mushrooms', 'onions', 'pineapple']
    'mushrooms' in request_toppings

    判断特定值是否不包含在列表中
    if 'mushrooms' not in request_toppings:

    if else
    if elif else
    if

    第六章 字典

    字典:包含key-value键值对的数据结构。
    alien={'color':'green', 'points':5}
    可将任何字段用作key,包括数字、字符串、列表乃至字典。

    访问字典中的值
    alien['color']

    添加键值对
    alien['x_position']=0
    alien['y_position']=250

    空字段
    alien={}

    修改字典中的值
    alien['color']=‘yellow'

    删除键值对
    del alien['points']

    遍历字典
    for key,value in alien:
    print(key,value)
    注意,键值对返回的顺序和存储顺序不同,Python不关心键值对的存储顺序,而只关心键值对之间的关联关系。

    遍历字典中的所有键
    for key in alien.keys():#for key in alien效果一样

    按顺序遍历字典中所有键
    要以特定的顺序返回元素,一种方法是在for循环中对返回的键进行排序,为此,可以用sorted()来排序
    for key in sorted(alien.keys()):

    遍历字典中所有值
    for value in alien.values():

    如果值有重复,那输出重复的值没有意义,如何去重:可以使用集合
    for value in set(alien.values()):

    嵌套
    字典列表
    alien_0={'color':'green', 'points':5}
    alien_1={'color':'yellow', 'points':10}

    aliens = [alien_0, alien_1]

    在字典中存储列表
    pizza = {'crust':'thick', 'topping': ['mushroom','extra cheese'],}

    在字典中存储字典

    用户输入和while循环

    name = input("Please enter your name:")
    print(name)
    input()将用户输入解读为字符串
    如果输入的是数字字符串,可以通过int()将其转化成数字

    求模运算符
    4%3
    求模运算符,将两个数相除并符合余数。

    active = True
    while active:
    message=input()
    if message == 'quit':
    active = False
    else:
    print(message)

    另一种写法:break
    使用break退出循环
    while True:
    message=input()
    if message == 'quit':
    break
    else:
    print(message)

    continue:继续使用循环,从头开始执行
    打印10以内的奇数
    current_number = 0
    while current_number < 10:
    current_number += 1
    if current_number % 2 == 0:
    continue
    print(current_number)

    for循环是一种遍历列表的有效方式,但在for循环中不应该修改列表,否则将导致python难以跟踪其中元素。如果要在遍历列表的同时对其修改,可以使用while循环。

    unconfirmed_users = ['alice','brain', 'candace']

    while unconfirmed_users:
    current_user = unconfirmed_users.pop()

    删除包含特定值的所有列表元素
    pets = ['dog','cat','dog','goldfish','cat','rabbit','cat']

    while 'cat' inpets:
    pets.remove('cat')

    函数

    def greet_user(username):
    print("hello!," + username.title() + "!")

    greet_user('sarah')
    实参和形参
    username是一个形参,'sarah'是一个实参。将实参'sarah'传递给函数的形参username,值被存储在形参username中。

    位置实参
    def describe_pet(animal_type, pet_name):
    print("\nI have a " + animal_type +".")
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")
    describe_pet('dog', 'willie')
    调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参,最简单的关联方式就是基于实参的顺序。这种关联方式称为位置实参。

    关键字实参
    关键字实参是传递给函数的名称-值对。你直接在实参中将名称和值关联起来。因此向函数传递实参时不会混淆。关键字实参让你无需考虑函数调用中的实参顺序,还清楚的指出了函数调用中各值的用途。
    describe_pet(animal_type = 'dog', pet_name = 'willie')

    默认值
    def describe_pet(pet_name, animal_type='dog'):
    print("\nI have a " + animal_type +".")
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")

    describe_pet(pet_name='willie')
    也可以通过位置实参调用
    describe_pet('willie')
    使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的形参。这让Python依然能够正确解读位置参数。

    返回值
    def get_formatted_name(first_name, last_name):
    full_name = first_name + ' ' + last_name
    return full_name.title()

    返回字典
    def build_person(first_name,last_name):
    person = {'first_name':first_name,'last_name':last_name}
    return person

    禁止函数修改列表
    有时候,我们需要禁止修改列表。为了解决这个问题,可以向函数传递列表的副本,而不是列表本身,这样对列表的修改只是在副本上。不会影响列表本身。也就是传递列表的切片
    function(last_name(:))

    传递任意数量的实参
    一个制作披萨的函数,它需要接受很多配料,但你无法预先确定顾客要多少种配料。
    def make_pizza(*toppings):
    for topping in toppings:
    print("- " + topping)

    make_pizza('pepperoni')
    make_pizza('mushrooms','green peppers','extra cheese')
    形参名*toppings中的星号让Python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中。

    结合使用位置实参和任意数量实参
    如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
    def make_pizza(size, *toppings):
    print("\nMaking a "+ str(size) + "-inch pizza with following toppings:")
    for topping in toppings:
    print("- " + topping)
    make_pizza(16,'pepperoni')
    基于函数定义,Python将第一个值存储在形参中,并将其他所有值存储在元组toppings中。

    使用任意数量的关键字实参
    def build_profile(first, last, **user_info):
    profile={}
    profile['first_name'] = first
    profile['last_name'] = last
    for key,value in user_info:
    profile[key] = value
    return profile

    build_profile('albert', 'einstein', location='princeton', field='physics')
    函数的定义要求提供名和姓,同时允许用户根据需要提供任意数量的名称-键值对,形参*user_inmfo中的两个号让Python创建一个名为user_info的空字典。并将收到的所有键值对都封装到这个字典中。可以像访问其他字典那样访问user_info键值对

    将函数存储在模块中,可以通过import来使用模块中的函数
    导入整个模块

    pizza.py
    def make_pizza(size, *toppings):
    print("\nMaking a "+ str(size) + "-inch pizza with following toppings:")
    for topping in toppings:
    print("- " + topping)

    我们在pizza.py目录创建另一个making_pizzas.py文件,导入pizzs模块,再调用make_pizza()两次
    making_pizzas.py
    import pizza

    pizza.make_pizza(16, 'pepperoni')
    pizza.make_pizza(12, 'mushrooms','green peppers','extra cheese')

    Python读取这个文件时,代码行import pizza让Python打开文件pizza.py,并将其中的所有的函数都复制到这个程序中。调用方法就是模块名,后面加.,最后再加函数名
    module_name.fuction_name()

    导入特定函数
    from module_name import fuction_name0, fuction_name1
    通过这种方式导入的函数,可以直接用fuction_name0()进行调用

    使用as给指定函数指定别名
    如果要导入的函数的名称可能与程序中的现有名称冲突,或者函数名称太长,可指定简短且独一无二的别名。
    from module_name import function_name as fn

    from pizza import make_pizza as mp

    mp(16, 'pepperoni')
    mp(12, 'mushrooms','green peppers','extra cheese')

    使用as给模块指定别名
    import module_name as mn

    import pizza as p

    p.make_pizza(16, 'pepperoni')
    p.make_pizza(12, 'mushrooms','green peppers','extra cheese')

    导入模块中所有函数
    from pizza import *

    make_pizza(16, 'pepperoni')
    make_pizza(12, 'mushrooms','green peppers','extra cheese')

    import语句中的*让Python将模块pizza中的每个函数都复制到这个程序文件中。由于导入了每个函数,可通过名称来调用每个函数,而无需使用句点表示法。然而,使用并非自己编写的大型模块时,最好不要采用这种导入方法:如果模块中有函数的名称与你的项目中使用的名称相同,可能导致意想不到的结果:Python可能遇到多个名称相同的函数活变量,进而覆盖函数,而不是分别导入所有的函数。
    最佳的做法是,要么只导入你需要用的函数,要么导入整个模块并使用句点法

    函数编写指南
    1、函数名称只用小写字母和下划线
    2、函数都应包含简要阐述期功能的注释
    3、参数的意义的注释

    第九章 类

    创建dog类

    class Dog():
        """一次模拟小狗的简单尝试"""
        def __init__(self, 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.")
    

    方法 init()
    类中的函数称为方法,init()是一个特殊的方法,每当你根据Dog类创建新实例时,Python就会自动运行它。在这个方法的名称中,开头和结尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生冲突。

    init()包含三个形参,self、name和age。在这个方法的定义中,形参self必不可少,还必须位于其他形参的前面。因为Python调用init()方法创建Dog实例时,将自动传入实参self。每个与类相关联的方法调用都自动传递实参self,它是指向实例本身的引用,让实例能够访问类中的属性和方法。我们创建Dog实例时,Python将调用Dog类的方法,init(),我们将通过实参向Dog()传递名字和年龄,self会自动传递。

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

    Dog类还定义了另外两个方法:sit()和roll_over()。由于这些方法不需要额外的参数,因此他们只有一个形参self。

    根据类创建实例
    my_dog = Dog('willie', 6)###调用init()创建特定小狗实例

    print("My dog's name is " + my_dog.name.title() + ".")
    print("My dog's is " + str(my_dog.age) + " years old.")

    访问属性
    要访问实例的属性,可使用句点法表示。my_dog.name

    调用方法
    my_dog.sit()

    使用类和实例

    class Car():
        """一次模拟汽车的简单尝试"""
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
            
        def get_descriptive_name(self):
            long_name = str(self.year) + ' ' + self.make + ' ' + self.model
            return long_name.title()
    

    my_new_car = Car("audi", "a4", 2016)

    给属性指定默认值

    class Car():
        """一次模拟汽车的简单尝试"""
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
            self.odometer = 0
            
        def get_descriptive_name(self):
            long_name = str(self.year) + ' ' + self.make + ' ' + self.model
            return long_name.title()
            
        def read_odometer(self):
            print("This car has " + str(self.odometer_reading) + " miles on it.")
    

    修改属性的值
    my_new_car.odometer = 23
    my_new_car.read_odometer()

    通过方法修改属性的值

    class Car():
        """一次模拟汽车的简单尝试"""
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
            self.odometer = 0
            
        def get_descriptive_name(self):
            long_name = str(self.year) + ' ' + self.make + ' ' + self.model
            return long_name.title()
            
        def read_odometer(self):
            print("This car has " + str(self.odometer_reading) + " miles on it.")
        def update_odometer(self, mileage):
            self.odomter = mileage
    

    my_new_car.update_odometer(23)

    通过方法对属性的值进行递增
    def increment_odometer(self, miles):
    self.odometer += miles

    my_new_car.increment_odometer(50)

    class Car():
        """一次模拟汽车的简单尝试"""
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
            self.odometer = 0
            
        def get_descriptive_name(self):
            long_name = str(self.year) + ' ' + self.make + ' ' + self.model
            return long_name.title()
            
        def read_odometer(self):
            print("This car has " + str(self.odometer_reading) + " miles on it.")
        def update_odometer(self, mileage):
            self.odomter = mileage
            
        def increment_odometer(self, miles):
            self.odometer += miles
            
    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())

    创建子类时,父类必须包含在当前文件中,且位于子类之前。
    super()函数是一个特殊函数,帮助Python将父类和子类关联起来。

    给子类定义属性和方法

    class Car():
        """一次模拟汽车的简单尝试"""
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
            self.odometer = 0
            
        def get_descriptive_name(self):
            long_name = str(self.year) + ' ' + self.make + ' ' + self.model
            return long_name.title()
            
        def read_odometer(self):
            print("This car has " + str(self.odometer_reading) + " miles on it.")
        def update_odometer(self, mileage):
            self.odomter = mileage
            
        def increment_odometer(self, miles):
            self.odometer += miles
            
    class  ElectricCar(Car):
        """电动汽车的独特之处"""
        
        def __init__(self, make, model, year):
            super().__init__(make, model, year)
            self.battery_size = 70
            
        def describe_battery(self):
            print("This car has a " + str(self.battery_size) + "-kwh battery.")
    

    my_tesla.describe_battery()

    重写父类方法
    假设Car类有一个名为fill_gas_tank()的方法,它对电动汽车毫无意义,因此可以重写他

    class  ElectricCar(Car):
        --snip--
        
        def fill_gas_tank(self):
            print("This car doesn't need a gas tank!")
    

    将实例用作属性
    可能需要将类的一部分作为一个独立的类提取出来。可以将大型类拆分成多个协同工作的小类。

    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()

    导入类
    由于类不断的添加功能,文件变的很长,为了让文件尽可能整洁,Python允许你将类存储在模块中,然后在主程序中导入所需模块

    导入单个类
    car.py

    """一个可用于表示汽车的类"""
    
    class Car():
        """一次模拟汽车的简单尝试"""
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
            self.odometer = 0
            
        def get_descriptive_name(self):
            long_name = str(self.year) + ' ' + self.make + ' ' + self.model
            return long_name.title()
            
        def read_odometer(self):
            print("This car has " + str(self.odometer_reading) + " miles on it.")
        def update_odometer(self, mileage):
            self.odomter = mileage
            
        def increment_odometer(self, miles):
            self.odometer += miles
    

    my_car.py

    from car import Car##从文件中导入类,可用利用逗号,一次引入多个类
    
    my_new_car = Car('audi', 'a4', 2016)
    print(my_new_car.get_descriptive_name())
    
    my_new_car.odometer  = 23
    my_new_car.read_odometer()
    

    导入整个模块
    可用import car导入整个模块。接下来,我们使用module_name.class_name访问需要的类

    导入模块所有类
    from car import *
    不推荐这种导入方式,其原因有二:
    1、如果只要看一下文件开头的import语句,就能清楚知道程序使用了哪些类,将大有裨益。但这种方式并没有明确你使用了模块中哪些类
    2、这种导入方式还可能引发名称方面的困惑。如果你不小心导入了一个与程序文件中其他同名的类,可能引发错误。

    在一个模块中引入另一个模块
    这个用法和普通的模块引入没有任何区别,比如把Car类和ElectricCar分成两个模块文件,任何在ElectricCar里面from car import Car
    后面如果需要导入Car和ElectricCar类的时候,不能以为ElectricCar类里面导入了Car就不需要再导入了。所以,Car类和ElectricCar类都需要单独导入。

    类编码风格
    1、类名应采取驼峰命名法,将类名中的每个首字母大写,而不使用下划线。实例名和模块名都是小写格式,并在单词之间加上下划线。
    2、对于每个类,都应紧跟在类定义后面包含一个文档字符串。描述累的功能。每个模块也都要包含一个文档字符串,对其中的类的行为进行描述
    3、在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。
    4、需要同时导入标准库中的模块和你自己编写的模块时,先导入标准库模块的import语句,再添加一个空行,然后再编写导入你自己编写的模块的import语句。这种做法让人更容易明白程序使用的各个模块来自何方。

    总结:
    除了类名是驼峰命名法,首字母大写,其他比如实例、模块名、函数名、方法名、变量名都是小写加下划线,导入变量名还可以加数字。

    第十章 文件和异常

    with open('pi_digits.txt') as file_object:
    contents = file_object.read()
    print(contents)

    这里有调用open(),但是没有调用close()。用with打开文件,Python会自动在合适的时候调用close()关闭文件。
    这个输出会多一行,原因在于read()到达文件末尾时返回一个空字符串,而将这个空字符串显示出来就是一个空行。要删除空行,可以在print里面使用rstrip()
    print(contents.rstrip())

    上面的open的文件没有带路径,Python会自动搜索程序文本所在的当前文件夹。

    文件路径
    相对路径
    linux和os x系统
    with open('text_files/filename.txt') as file_object

    windows系统
    with open('text_files\filename.txt') as file_object

    绝对路径
    linux和os x系统
    file_path = '/home/ehmatthes/text_files/filename.txt'
    with open(file_path) as file_object

    windows系统
    file_path = 'C:\Users\ethmatthes\other_files\text_files\filename.txt'
    with open(file_path) as file_object

    逐行读取
    filename = 'pi_digits.txt'

    with open(filename) as file_object:
    for line in file_object:
    print(line.rstrip())

    调用open后,将一个表示文件及其内容的对象存储到变量file_object中。

    创建一个包含文件各行内容的列表
    filename = 'pi_digits.txt'

    with open(filename) as file_object:
    for line in file_object:
    lines = file_object.readlines()

    for line in lines:
    print(line.strip())

    lines列表中的每个元素就是file_object的每一行内容。

    filename = 'pi_millon_digits.txt'

    with open(filename) as file_object:
    lines = file_object.readlines()

    pi_string = ''
    for line in lines:
    pi_string += line.strip()

    print(pi_string[:52] + "...")

    圆周率是否包含你的生日

    filename = 'pi_millon_digits.txt'

    with open(filename) as file_object:
    lines = file_object.readlines()

    pi_string = ''
    for line in lines:
    pi_string += line.strip()

    birthday = input("Enter your birthday, in the form mmddyy:")
    if birthday in pi_string:
    print("Your birthday appears in the first millon digits of pi!")
    else:
    print("Your birthday does not appears in the first millon digits of pi!")

    写入文件
    filename = 'programming.txt'

    with open(filename,'w') as file_object:
    file_object.write("I love programming.")

    调用open时,提供了两个参数,第一个参数是要打开的文件的名称,第二个参数'w'告诉Python,我们要以写入的方式打开文件。
    打开文件有几种模式
    w-写入模式
    r-只读模式
    a-附加模式
    r+-读取和写入模式
    如果省略模式实参,那Python默认以只读打开

    如果要写入的文件不存在,函数open()自动创建它。以'w'模式打开文件要小心,如果文件以及存在,Python将返回对象前清空该文件。

    Python只能将字符串写入文本文件。要将数值数据存储到文本文件,必须先试用str()函数将其转换为字符串格式。

    写入多行
    file_object.write("I love programming.\n")
    file_object.write("I love creating new game.\n")
    如果不加换行符,则会连成一行

    附加到文件
    如果你想给文件添加内容,而不是覆盖原有的内容,可以附加模式打开文件。你以附加模式打开文件时,Python不会再返回文件对象前清空文件,而你写入到文件的行都将添加到文件末尾。如果你指定的文件不存在,Python将为你创建一个空文件。

    异常
    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)
    else:
    words = contents.split()
    num_words = len(words)
    print("The file " + filename + " has about " + str(num_words) + " words.")

    存储数据
    使用json.dump()和json.load()
    函数json.dump()接受两个实参,要存储的数据以及可用于存储数据的文件对象。

    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 remeber you when you come back, " + username + "!")
    else:
    print("Welcome back, " + username + "!")

    第十一章 测试代码

    name_function.py
    def get_formatted_name(first_name, last_name):
    full_name = first_name + ' ' + last_name
    return full_name.title()

    names.py

    from name_function import get_formatted
    
    print("Enter 'q' at any time to quit.")
    while True:
        first = input("\nPlease give me a first name:")
        if first == 'q':
            break
        last = input("\nPlease give me a last name:")
        if last == 'q':
            break
            
        formatted_name = get_formatted_name(first,last)
        print("\tNeatly formatted name:" + formatted_name + '.')
    

    单元测试
    test_name_function.py

    import unittest
    from name_function import get_formatted_name
    
    class NameTestCase(unittest.TestCase):
        """测试name_function.py"""
        
        def test_first_last_name(self):
            formatted_name = get_formatted_name('janis', 'joplin')
            self.assertEqual(formatted_name, 'Janis Joplin')
            
    unittest.main()
    

    首先我们创建了一个名为NameTestCase的类,用于包含一系列针对get_formatted_name()的单元测试。你可以随便给这个类命名,但最好让它看起来与测试的函数相关,并包含Test字样。这个类必须继承unittest.TestCase类,这样Python才知道如何运行你编写的测试。
    NameTestCase只包含一个方法,用于测试get_formatted_name()的一个方面。我们将这个方法命名为test_first_last_name()。
    我们运行test_name_function.py时,所有以test_打头的方法都将自动运行。

    方法里,我们使用了unittest类最常用的功能之一:一个断言方法。断言方法用来合适得到的结果是否与期望的结果一致。
    unittest断言方法

    方法 用途
    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中

    测试类
    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)
    

    测试AnonymousSurvey类
    test_survey.py

    import unittest
    from survey import AnonymousSurvey
    
    
    class TestAnonymousSurvey(unittest.TestCase):
        """针对AnonymousSurvey类的测试"""
    
        def setUp(self):
            question = "What language did you first leanr 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_response(self):
            for response in self.responses:
                self.my_survey.store_response(response)
    
            for response in self.responses:
                self.assertIn(response, self.my_survey.responses)
    
    unittest.main()
    

    方法setUp()
    在前面的测试代码中,我们在测试方法中都单独创建了AnonymousSurvey的实例。
    有没有办法进行优化?
    可以使用setUp(),让我们只需创建这些对象一次,并在每个测试方法中运用它们。
    如果你在TestCase类中包含方法setUp(),Python将先运行它,再运行各个以test_打头的方法。

    import unittest
    from survery import AnonymousSurvey
    
    class TestAnonymousSurvey(unittest.TestCase):
        """针对AnonymousSurvey类的测试"""
        
        def setUp(self):
            question = "What language did you first leanr to speak?"
            self.survey = AnonymousSurvey(question)
            self.responses = ['English', 'Spanish', 'Mandarin']
        
        def test_store_single_response(self):
            my_survey.store_response(self.responses[0]) 
            self.assertIn(self.responses[0], my_survey.response)
            
        def test_store_three_response(self):
            for response in responses:
                my_survey.store_response(response)
                
            for response in responses:
                self.assertIn(response, my_survey.responses)
    unittest.main()
    

    相关文章

      网友评论

          本文标题:Python基础

          本文链接:https://www.haomeiwen.com/subject/hgjhyktx.html