极简Python入门
安装
https://www.python.org/downloads/
image.png数据类型
变量
#定义变量message
message = "Hello Python world!"
print(message)
字符串
就是一系列字符。在Python中,用引号括起的都是字符串,其中的引号可以是单引号,也可以是双引号,如下所示:
"This is a string."
'This is also a string.'
如下f开头的写法这种字符串名为f字符串 。f是format(设置格式)的简写,可通过把花括号内的变量替换为其值来设置字符串的格式。
first_name = "ada"
last_name = "lovelace"
full_name = f"{first_name} {last_name}"
print(full_name)
字符串扩展:http://study.yali.edu.cn/pythonhelp/library/stdtypes.html#str
数字:整数,浮点数
Python将所有带小数点的数称为浮点数 。
将任意两个数相除时,结果总是浮点数,即便这两个数都是整数且能整除:
在其他任何运算中,如果一个操作数是整数,另一个操作数是浮点数,结果也总是浮点数
书写很大的数时,可使用下划线将其中的数字分组,使其更清晰易读:
>>> universe_age = 14_000_000_000
数字类型扩展:http://study.yali.edu.cn/pythonhelp/library/stdtypes.html#numeric-types-int-float-complex
布尔值
game_active = True
can_edit = False
常量
类似于变量,但其值在程序的整个生命周期内保持不变。Python没有内置的常量类型,但Python程序员会使用全大写来指出应将某个变量视为常量,其值应始终不变:
可在一行代码中给多个变量赋值,这有助于缩短程序并提高其可读性。这种做法最常用于将一系列数赋给一组变量
>>> x, y, z = 0, 0, 0
数据结构
列表list
列表 由一系列按特定顺序排列的元素组成,用方括号([] )表示列表,并用逗号分隔其中的元素。 第一个列表元素的索引为0,而不是1。
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles[0])
方法append() 将元素'ducati' 添加到列表末尾
使用方法insert() 可在列表的任何位置添加新元素。为此,你需要指定新元素的索引和值
motorcycles = ['honda', 'yamaha', 'suzuki']
motorcycles.insert(0, 'ducati')
print(motorcycles)
使用del 语句删除元素
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)
del motorcycles[0]
print(motorcycles)
使用方法pop() 删除元素, 方法pop() 删除列表末尾的元素,并让你能够接着使用它。
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)
popped_motorcycle = motorcycles.pop()
print(motorcycles)
print(popped_motorcycle)
可以使用pop() 来删除列表中任意位置的元素,只需在圆括号中指定要删除元素的索引即可。
motorcycles = ['honda', 'yamaha', 'suzuki']
first_owned = motorcycles.pop(0)
print(f"The first motorcycle I owned was a {first_owned.title()}.")
根据值删除元素, 假设要从列表motorcycles 中删除值'ducati' 。
motorcycles = ['honda', 'yamaha', 'suzuki', 'ducati']
print(motorcycles)
motorcycles.remove('ducati')
print(motorcycles
使用方法sort() 对列表永久排序
使用函数sorted() 对列表临时排序
要反转列表元素的排列顺序,可使用方法reverse()
使用函数len() 可快速获悉列表的长度
函数range() 让你能够轻松地生成一系列数。
for value in range(1, 5):
print(value)
要创建数字列表,可使用函数list() 将range() 的结果直接转换为列表。如果将range() 作为list() 的参数,输出将是一个数字列表
numbers = list(range(1, 6))
print(numbers)
要创建切片,可指定要使用的第一个元素和最后一个元素的索引。
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[0:3])
如果要遍历列表的部分元素,可在for 循环中使用切片
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print("Here are the first three players on my team:")
for player in players[:3]:
print(player.title())
要复制列表,可创建一个包含整个列表的切片,方法是同时省略起始索引和终止索引([:] )。
元组tuple
如果需要创建一系列不可修改的元素,可使用元组。Python将不能修改的值称为不可变的 ,而不可变的列表被称为元组 。
元组看起来很像列表,但使用圆括号()而非中括号来标识。定义元组后,就可使用索引来访问其元素,就像访问列表元素一样。
dimensions = (200, 50)
print(dimensions[0])
print(dimensions[1])
for dimension in dimensions:
print(dimension)
字典dict
在Python中,字典 是一系列键值对 。每个键 都与一个值相关联,你可使用键来访问相关联的值。与键相关联的值可以是数、字符串、列表乃至字典。事实上,可将任何Python对象用作字典中的值。字典用放在花括号({} )中的一系列键值对表示。
将一系列字典存储在列表中,或将列表作为值存储在字典中,这称为嵌套 。你可以在列表中嵌套字典、在字典中嵌套列表甚至在字典中嵌套字典。
# 可创建空字典
alien_0 = {}
alien_0 = {'color': 'green', 'points': 5}
# 要获取与键相关联的值,可依次指定字典名和放在方括号内的键
print(alien_0['color'])
#字典是一种动态结构,可随时在其中添加键值对。要添加键值对,可依次指定字典名、用方括号括起的键和相关联的值。
alien_0['x_position'] = 0
alien_0['y_position'] = 25
print(alien_0)
# 修改字典中的值
alien_0['color'] = 'yellow'
print(f"The alien is now {alien_0['color']}.")
# 删除键值对
del alien_0['points']
print(alien_0)
#由类似对象组成的字典
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
language = favorite_languages['sarah'].title()
print(f"Sarah's favorite language is {language}.")
# 使用方法get() 在指定的键不存在时返回一个默认值
alien_0 = {'color': 'green', 'speed': 'slow'}
point_value = alien_0.get('points', 'No point value assigned.')
print(point_value)
# 遍历所有键值对
user_0 = {
'username': 'efermi',
'first': 'enrico',
'last': 'fermi',
}
for k, v in user_0.items():
print(f"\nKey: {k}")
print(f"Value: {v}")
# 使用keys()遍历字典中的所有键
for k in user_0.keys():
print(f"\nKey: {k}")
# 使用方法values() 遍历字典中的所有值
for v in user_0.values():
print(f"Value: {v}")
字典扩展:http://study.yali.edu.cn/pythonhelp/library/stdtypes.html#dict
控制语句
for循环
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(f"{magician.title()}, that was a great trick!")
if语句
每条if 语句的核心都是一个值为True 或False 的表达式,这种表达式称为条件测试 。Python根据条件测试的值为True 还是False 来决定是否执行if 语句中的代码。
使用两个等号(== )检查car 的值是否为'bmw' 。这个相等运算符 在两边的值相等时返回True ,否则返回False
>>> car = 'Audi'
>>> car == 'audi'
False
>>> car.lower() == 'audi'
True
要判断两个值是否不等,可结合使用惊叹号和等号(!= ),其中的惊叹号表示不,其他很多编程语言中也是如此。 条件语句中可包含各种数学比较,如小于、小于等于、大于、大于等于:
数值比较
>>> age = 18
>>> age == 18
True
answer = 17
if answer != 42:
print("That is not the correct answer. Please try again!")
>>> age = 19
>>> age < 21
True
>>> age <= 21
True
>>> age > 21
False
>>> age >= 21
使用and 检查多个条件, 使用or检查多个条件
>>> age_0 = 22
>>> age_1 = 18
>>> age_0 >= 21 and age_1 >= 21
False
>>> age_1 = 22
>>> age_0 >= 21 and age_1 >= 21
True
>>> age_0 = 22
>>> age_1 = 18
>>> age_0 >= 21 or age_1 >= 21
True
>>> age_0 = 18
>>> age_0 >= 21 or age_1 >= 21
False
检查特定值是否包含在列表中, 要判断特定的值是否已包含在列表中,可使用关键字in
>>> requested_toppings = ['mushrooms', 'onions', 'pineapple']
>>> 'mushrooms' in requested_toppings
True
>>> 'pepperoni' in requested_toppings
False
banned_users = ['andrew', 'carolina', 'david']
user = 'marie'
if user not in banned_users:
print(f"{user.title()}, you can post a response if you wish.")
age = 12
if age < 4:
print("Your admission cost is $0.")
elif age < 18:
print("Your admission cost is $25.")
else:
print("Your admission cost is $40.")
在if 语句中将列表名用作条件表达式时,Python将在列表至少包含一个元素时返回True ,并在列表为空时返回False
requested_toppings = []
if requested_toppings:
for requested_topping in requested_toppings:
print(f"Adding {requested_topping}.")
print("\nFinished making your pizza!")
else:
print("Are you sure you want a plain pizza?")
while 循环
#使用break
while True:
city = input(prompt)
if city == 'quit':
break
else:
print(f"I'd love to go to {city.title()}!")
#使用continue
current_number = 0
while current_number < 10:
current_number += 1
if current_number % 2 == 0:
continue
print(current_number)
# 首先,创建一个待验证用户列表和一个用于存储已验证用户的空列表。
unconfirmed_users = ['alice', 'brian', 'candace']
confirmed_users = []
# 验证每个用户,直到没有未验证用户为止。
# 将每个经过验证的用户都移到已验证用户列表中。
while unconfirmed_users:
current_user = unconfirmed_users.pop()
print(f"Verifying user: {current_user.title()}")
confirmed_users.append(current_user)
# 显示所有已验证的用户。
print("\nThe following users have been confirmed:")
for confirmed_user in confirmed_users:
print(confirmed_user.title())
函数
def greet_user(username):
"""显示简单的问候语。"""
print(f"Hello, {username.title()}!")
greet_user('jesse')
用def定义一个函数,文档字符串 (docstring)用三引号的注释,描述了函数是做什么的。Python使用它们来生成有关程序中函数的文档。
实参和形参
在函数greet_user() 的定义中,变量username 是一个形参 (parameter),即函数完成工作所需的信息。在代码greet_user('jesse') 中,值'jesse' 是一个实参 (argument),即调用函数时传递给函数的信息。调用函数时,将要让函数使用的信息放在圆括号内。在greet_user('jesse') 中,将实参'jesse' 传递给了函数greet_user() ,这个值被赋给了形参username 。
函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。向函数传递实参的方式很多:可使用位置实参 ,这要求实参的顺序与形参的顺序相同;也可使用关键字实参 ,其中每个实参都由变量名和值组成;还可使用列表和字典。
- 位置实参:
#位置实参
def 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')
- 关键字实参:
是传递给函数的名称值对。因为直接在实参中将名称和值关联起来,所以向函数传递实参时不会混淆(不会得到名为Hamster的harry这样的结果)。关键字实参让你无须考虑函数调用中的实参顺序,还清楚地指出了函数调用中各个值的用途。
def 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(animal_type='hamster', pet_name='harry')
编写函数时,可给每个形参指定默认值 。在调用函数中给形参提供了实参时,Python将使用指定的实参值;否则,将使用形参的默认值。
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()}.")
describe_pet(pet_name='willie')
混合使用位置实参、关键字实参和默认值,通常有多种等效的函数调用方式。
def describe_pet(pet_name, animal_type='dog'):
#使用
# 一条名为Willie的小狗。
describe_pet('willie')
describe_pet(pet_name='willie')
# 一只名为Harry的仓鼠。
describe_pet('harry', 'hamster')
describe_pet(pet_name='harry', animal_type='hamster')
describe_pet(animal_type='hamster', pet_name='harry')
函数返回值 。在函数中,可使用return 语句将值返回到调用函数的代码行。 函数可返回任何类型的值,包括列表和字典等较复杂的数据结构
def get_formatted_name(first_name, last_name):
"""返回整洁的姓名。"""
full_name = f"{first_name} {last_name}"
return full_name.title()
musician = get_formatted_name('jimi', 'hendrix')
print(musician)
传递任意数量的实参
有时候,预先不知道函数需要接受多少个实参,好在Python允许函数从调用语句中收集任意数量的实参。
def make_pizza(*toppings):
"""概述要制作的比萨。"""
print("\nMaking a pizza with the following toppings:")
for topping in toppings:
print(f"- {topping}")
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')
#结合使用位置实参和任意数量实参
def make_pizza(size, *toppings):
"""概述要制作的比萨。"""
print(f"\nMaking a {size}-inch pizza with the following toppings:")
for topping in toppings:
print(f"- {topping}")
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
形参名*toppings 中的星号让Python创建一个名为toppings 的空元组,并将收到的所有值都封装到这个元组中。
使用任意数量的关键字实参
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',field='physics')
print(user_profile)
函数build_profile() 的定义要求提供名和姓,同时允许根据需要提供任意数量的名称值对。形参**user_info 中的两个星号让Python创建一个名为user_info的空字典,并将收到的所有名称值对都放到这个字典中。在这个函数中,可以像访问其他字典那样访问user_info 中的名称值对。
模块
将函数存储在称为模块 的独立文件中,再将模块导入 到主程序中。import 语句允许在当前运行的程序文件中使用模块中的代码。
要让函数是可导入的,得先创建模块。模块 是扩展名为.py的文件,包含要导入到程序中的代码。
文件pizza.py
def make_pizza(size, *toppings):
"""概述要制作的比萨。"""
print(f"\nMaking a {size}-inch pizza with the following toppings:")
for topping in toppings:
print(f"- {topping}")
文件 making_pizzas.py
import pizza
pizza.make_pizza(16, 'pepperoni')
pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
#如果使用这种import 语句导入了名为module_name.py的整个模块,就可使用下面的语法来使用其中任何一个函数:
module_name.function_name()
#导入特定的函数
from module_name import function_name
from module_name import function_0, function_1, function_2
#使用as 给函数指定别名
from pizza import make_pizza as mp
#使用as 给模块指定别名
import pizza as p
#导入模块中的所有函数
from pizza import *
最佳的做法是,要么只导入需要使用的函数,要么导入整个模块并使用句点表示法。
注释
在Python中,注释用井号(# )标识。
# 向大家问好。
print("Hello Python people!")
类
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!")
类中的函数称为方法 。方法__init__() 是一个特殊方法,每当你根据Dog 类创建新实例时,Python都会自动运行它。在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。务必确保__init__() 的两边都有两个下划线,否则当你使用类来创建实例时,将不会自动调用这个方法,进而引发难以发现的错误。
在这个方法的定义中,形参self 必不可少,而且必须位于其他形参的前面。为何必须在方法定义中包含形参self 呢?因为Python调用这个方法来创建Dog 实例时,将自动传入实参self 。每个与实例相关联的方法调用都自动传递实参self ,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
根据类创建实例
class Dog:
--snip--
my_dog = Dog('Willie', 6)
print(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old.")
继承
一个类继承 另一个类时,将自动获得另一个类的所有属性和方法。原有的类称为父类 ,而新类称为子类 。子类继承了父类的所有属性和方法,同时还可以定义自己的属性和方法。
class Car:
"""一次模拟汽车的简单尝试。"""
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descriptive_name(self):
long_name = f"{self.year} {self.make} {self.model}"
return long_name.title()
def read_odometer(self):
print(f"This car has {self.odometer_reading} miles on it.")
def update_odometer(self, mileage):
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!")
def increment_odometer(self, miles):
self.odometer_reading += miles
class ElectricCar(Car):
"""电动汽车的独特之处。"""
def __init__(self, make, model, year):
"""
初始化父类的属性。
再初始化电动汽车特有的属性。
"""
super().__init__(make, model, year)
self.battery_size = 75
def describe_battery(self):
"""打印一条描述电瓶容量的消息。"""
print(f"This car has a {self.battery_size}-kWh battery.")
my_tesla = ElectricCar('tesla', 'model s', 2019)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
super() 是一个特殊函数,让你能够调用父类的方法。这行代码让Python调用Car 类的方法__init__() ,让ElectricCar 实例包含这个方法中定义的所有属性。父类也称为超类 (superclass),名称super 由此而来。
给子类定义属性和方法
重写父类的方法
导入类
from car import Car
import 语句让Python打开模块car 并导入其中的Car 类
在一个模块中存储多个类
从一个模块中导入多个类 from car import Car, ElectricCar
导入整个模块 import car
文件
with open('pi_digits.txt') as file_object:
contents = file_object.read()
print(contents)
filename = 'pi_digits.txt'
with open(filename) as file_object:
for line in file_object:
print(line)
with open(filename) as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip())
关键字with 在不再需要访问文件后将其关闭
写入文件
filename = 'programming.txt'
with open(filename, 'w') as file_object:
file_object.write("I love programming.")
file_object.write("I love creating new games.")
打开文件时,可指定读取模式 ('r' )、写入模式 ('w' )、附加模式 ('a' )或读写模式 ('r+' )。如果省略了模式实参,Python将以默认的只读模式打开文件。
异常
Python使用称为异常 的特殊对象来管理程序执行期间发生的错误。每当发生让Python不知所措的错误时,它都会创建一个异常对象。如果你编写了处理该异常的代码,程序将继续运行;如果未对异常进行处理,程序将停止并显示traceback,其中包含有关异常的报告。
通过将可能引发错误的代码放在try-except 代码块中,可提高程序抵御错误的能力。错误是执行除法运算的代码行导致的,因此需要将它放到try-except 代码块中。这个示例还包含一个else 代码块。依赖try 代码块成功执行的代码都应放到else 代码块中
--snip--
while True:
--snip--
if second_number == 'q':
break
try:
answer = int(first_number) / int(second_number)
except ZeroDivisionError:
print("You can't divide by 0!")
else:
print(answer)
filename = 'alice.txt'
try:
with open(filename, encoding='utf-8') as f:
contents = f.read()
except FileNotFoundError:
print(f"Sorry, the file {filename} does not exist.")
else:
# 计算该文件大致包含多少个单词。
words = contents.split()
#使用pass,不处理异常
def count_words(filename):
"""计算一个文件大致包含多少个单词。"""
try:
--snip--
except FileNotFoundError:
pass
else:
--snip--
测试
Python标准库中的模块unittest提供了代码测试工具。单元测试 用于核实函数的某个方面没有问题。测试用例 是一组单元测试,它们一道核实函数在各种情形下的行为都符合要求。良好的测试用例考虑到了函数可能收到的各种输入,包含针对所有这些情形的测试。全覆盖 的测试用例包含一整套单元测试,涵盖了各种可能的函数使用方式。
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')
if __name__ == '__main__':
unittest.main()
如果这个文件作为主程序执行,变量__name__ 将被设置为'__main__'。
import unittest
from survey import AnonymousSurvey
class TestAnonymousSurvey(unittest.TestCase):
"""针对AnonymousSurvey类的测试。"""
def setUp(self):
"""
创建一个调查对象和一组答案,供使用的测试方法使用。
"""
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()
网友评论