6.用户输入和while循环
1)函数input()的工作原理
函数input()让程序暂停运行,等待用户输入一些文本,其接受一个参数——要向用户显示的提示或说明显示的提示或说明若有两行及以上:
prompt = "If you tell us who you are,we can personalize the messages you see" prompt += "\nWhat is your first name?"
可以使用int()来获取数值输入:
age=input("How old are you?") age = int(age) if age == 18: print("Yes!")
只有化为int后才可以比较大小。
2)while循环简介
循环读入消息直到遇到"quit":
prompt = "Tell me something!\nYou can enter 'quit' to end the program." message = "" while message != "quit": message = input(prompt) if message != "quit": print(message)
使用标志判断是否结束循环:
active = True message = "" while active: message = input("Input here:") if message == "quit": active = 0; else: print(message)
使用break可以跳出循环。
使用continue可以结束本次循环,进入下次循环。
3)使用while循环处理列表和字典
删除为特定值的所有列表元素:
pets = ["dog", "cat", "dog", "goldfish", "cat", "rabbit", "cat"] while 'cat' in pets: pets.remove("cat") print(pets)
7.函数
1)定义函数
def greet_user(): """显示简单的问候语。""" print("Hello!") greet_user()
第二行处的文本是称为文档字符串的注释,描述了函数是做什么的,用三引号括起,Python使用它们来生成有关程序中函数的文档。
2)传递实参
向函数传递实参的方式很多:可以使用位置实参,这要求实参的顺序与形参的顺序相同;
也可以使用关键字实参,期中每个实参都由变量名和值组成;
还可以使用列表和字典。
describe_pet(animal_type, pet_name): """显示宠物信息""" print(f"\nI have a {animal_type}.") print(f"My {animal_type}'s name is {pet_name.title()}.") """位置实参,关联方式基于实参的顺序""" describe_pet("hamster", "harry") """关键字实参,关联方式与位置顺序无关""" describe_pet(pet_name="harry", animal_type="hamster")
带有默认值的函数:
def describe_pet(pet_name, animal_type="dog"): print(f"\nI have a {animal_type}.") print(f"My {animal_type}'s name is {pet_name.title()}.")
在此函数定义中,必须交换形参的顺序,把带默认值的放在后面,否则编译失败。因为调用时输入的参数会按顺序赋给形参,如果放在前面则会把实参赋给带默认值的形参,而没带默认值的形参缺乏参数。
3)返回值
让实参变成可选:让可选择是否填写的实参放在参数列表最末位,如果是字符串,则赋值为"",如果是数值则赋值为None
然后函数定义中使用if语句,如
def get_formatted_name(first_name,last_name,middle_name=""): if middle_name: else:
4)传递列表
传递列表后再函数中修改列表会导致列表被改变,为了保留改变前的列表,可以禁止函数修改列表,
做法为:传递参数时将列表的副本传递给函数,如function_name(list_name[:])
5)传递任意数值的实参
有时候预先不知道函数需要接受多少个实参,则可以创建一个空元组,并将收到的所有值封装到这个元组,
def make_pizza(*toppings): """打印顾客点的所有配料""" for topping in toppings: print(f"-{topping}") make_pizza("pepperoni") make_pizza("mushrooms", "green peppers", "extra cheese")
要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。
Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
通用形参名L:*args
使用任意数量的关键字实参:
有时候需要接受任意数量的实参但预先不知道传递给函数的会是什么样的信息,在这种情况下可将函数编写成能够接受任意数量的键值对。
def build_profile(first, last, **user_info): """创建一个字典,其中包含我们知道的有关用户的一切信息""" user_info['first_name'] = first user_info['last_name'] = last return user_info user_profile = build_profile('albert', 'einstein', location='princeton', filed='physics') print(user_profile)
形参名**kwargs,用于收集任意数量的关键字形参
6)将函数存在模块中
可以将函数存储在称为模块的独立文件中,再将模块导入到主程序中。
import语句允许在当前运行的程序文件中使用模块中的代码。
导入整个模块:
模块是扩展名为.py的文件。创建完模块后在该文件所在目录中创建主程序,在主程序中调用该模块。
如:创建名为pizza.py的文件,后在主程序中使用代码import pizza,则可以使用该模块中的所有函数。
代码行import pizza让Python打开文件pizza.py,并将其中所有函数都复制到整个程序中(看不见)。
调用函数时:pizza.make_pizza(),即模块名.函数名
导入特定的函数:
from module_name import function_name(function0,function1,function2…)
如from pizza import make_pizza
使用as给函数指定别名:
如果导入函数名称可能与程序中现有的名称冲突或者函数名称太长,可指定简短而独一无二的别名:
函数的另一个名称,类似与外号。要给函数取这种特殊外号,需要在导入它时指定。
from pizza import make_pizza as mp mp(16, 'pepperoni') mp(12, 'mushrooms', 'green peppers', 'extra cheese')
使用as给模块指定别名:
import pizza as p p.make_pizza(16, 'pepperoni') p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') import
导入模块中的所有函数:
from pizza import *
,使用该语句引入函数后,调用时不需要通过句点表示法(模块名.函数名),可直接使用函数名调用,
然而因此名称相同时容易出现覆盖函数,一般不使用这种方式,
7)函数编写指南
给形参指定默认值时,等号两边不要有空格;
对于函数调用中的关键字实参,左右两边也不需要有空格;
函数命名时只是用小写字母和下划线,给函数指定描述性名称;
每个函数都应该包含简要的阐述其功能的注释,该注释应紧跟在函数定义后面;
如果形参很多导致函数定义的长度超过了79个字符,可在函数定义中输入左括号后按回车键,并在下一行按两次Tab键,从而将形参列表和只缩进一层的函数体区分开。如:
def function_name( xxx, xxxx, xxxxx, x, xxxxxx ): function body...
在程序或模块中包含多个函数,可使用两个空行将相邻的函数分开;
所有import语句都应放在文件开头,除非在文件开头使用了注释来描述整个程序。
8.类
1)创建和使用类
class Dog: """一次模拟小狗的简单尝试""" def __init__(self, name, age): """初始化属性name和age""" self.name = name self.age = age def sit(self): """模拟小狗收到命令时蹲下""" print(f"{self.name} is now sitting.") def roll_over(self): """模拟小狗收到命令时打滚""" print(f"{self.name} rolled over!")
类中的函数称为方法。
创建实例:my_dog = Dog("Willie", 6)
访问属性:my_dog.name
调用方法:my_dog.sit()
类名首字母大写,方法名小写
2)使用类和实例
修改属性的值:
直接修改属性的值:my_new_car.odometer_reading()
通过方法修改属性的值:
class Car: --snip-- def uodate_odometer(self, mileage): """ 将里程表读数设置为指定的值 禁止将里程表读数回调 """ if(mileage >= self.odometer_reading()): self.odometer_reading = mileage else: print("You can't roll back an odometer!")
3)继承
创建ElectricCar类的一个简单版本,它具备Car类的所有功能:
class ElectricCar(Car): """电动汽车的独特之处""" def __init__(self, make, model, year): """ 初始化父类的属性 再初始化电动汽车特有的属性 """ super.__init__(make, model, year) self.battery_size = 75 ma_tesla = ElectricCar("tesla","model s",2019) print(ma_tesla.get_descriptive_name())#调用父类的函数
创建子类时父类必须包含在当前文件中,且位于子类前面。
super是一个特殊函数,让你能够调用父类的方法。
在子类可以定义一个与要重写的父类方法同名的方法,这样即可覆盖父类的方法。
将实例用作属性:
当给类添加的细节越来越多时,属性和方法清单以及文件都越来越长,这是可以将类的一部分提取出来,作为一个独立的类。可以将大类型拆分成多个协同的小类。
class Battery: """一次模拟电动汽车电瓶的简单尝试""" def __init__(self, battery_size=75): """初始化电瓶的属性""" self.battery_size=battery_size def describe_battery(self): """打印一条描述电瓶容量的消息""" print(f"This car has a {self.battery_size}-kwh battery.") class ElectricCar(Car): """电动汽车的独特之处""" def __init__(self, make, model, year): """ 初始化父类的属性 再初始化电动汽车特有的属性 """ super.__init__(make, model, year) self.battery = Battery()#这行代码让Python创建了一个新的Battery实例(因为没有指定容量故为默认值75) my_tesla = ElectricCar("tesla", "model s'", 2019) my_tesla.battery.describe_battery()
在ElectricCar类中添加了一个名为self.battery的属性,并将创建的新的Battery实例赋给属性self.battery
4)导入类
from car import Car该语句让Python打开模块car.py并导入其中的Car类
from car import Car, ElectricCar从一个模块中导入多个类
import car 导入整个模块,访问类时用句点法(模块名.类名)
from car import *导入模块中所有类(不推荐使用,从模块中导入很多类时推荐导入整个模块,因为导入整个模块调用时需要带模块名,不会产生名称冲突)
from electric_car import ElectricCar as EC给导入的类指定一个别名,使用时可直接使用这个别名
5)Python标准库
Python标准库是一组模块,安装的Python中都包含。
模块random:
randint():将两个整数作为参数,并随机返回一个位于这两个整数之间(含)的整数。
choice():将一个列表或元组作为参数,并随机返回其中的一个元素
6)类编码风格
驼峰命名法:
类名中的每个单词的首字母都大写,不使用下划线
实例名和模块名都采用小写格式,每个单词之间加上下划线
对于每个类,都应紧跟在类定义后包含一个文档字符串来简要地描述该类的功能
每个模块也应该包含一个文档字符串来对其中的类可用于做什么进行描述
在类中可以用一个空行来分割方法
在模块中可以使用两个空行来分割类
需要同时导入标准库中的模块和自己编写的模块时,先编写导入标准库模块的import语句,再添加一个空行,然后编写导入你自己编写的模块的import语句