Python学习

2023-09-12  本文已影响0人  追风还是少年

字符串

first_name = "ada"
last_name = "lovelace"
full_name = f"{first_name} {last_name}"
print(full_name)
print(f"Hello, {full_name.title()}!")

这种字符串称为 f 字符串。f 是 format(设置格式)的简写,因为 Python 通
过把花括号内的变量替换为其值来设置字符串的格式

>>> nostarch_url = 'https://nostarch.com'
>>> nostarch_url.removeprefix('https://')
'nostarch.com'

整数

>>> 3 ** 2
9

浮点数

Python 将带⼩数点的数称为浮点数。
在 Python 中,⽆论是哪种运算,只要有操作数是浮点数,默认得到的就总
是浮点数,即便结果原本为整数

>>> 4/2
2.0
>>> 1 + 2.0
3.0
>>> 2 * 3.0
6.0
>>> 3.0 ** 2
9.0

其它

>>> universe_age = 14_000_000_000
>>> print(universe_age)
14000000000
>>> x, y, z = 0, 0, 0

注释

列表

bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles)
print(bicycles[0])
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)
motorcycles[0] = 'ducati'
print(motorcycles)
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)
motorcycles.append('ducati')
print(motorcycles)
motorcycles = []
motorcycles.append('honda')
motorcycles.append('yamaha')
motorcycles.append('suzuki')
print(motorcycles)

在列表中插⼊元素:

motorcycles = ['honda', 'yamaha', 'suzuki']
motorcycles.insert(0, 'ducati')
print(motorcycles)
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)

删除列表中任意位置的元素:

motorcycles = ['honda', 'yamaha', 'suzuki']
first_owned = motorcycles.pop(0)
print(f"The first motorcycle I owned was a {first_owned.title()}.")

根据值删除元素:

motorcycles = ['honda', 'yamaha', 'suzuki', 'ducati']
print(motorcycles)
motorcycles.remove('ducati')
print(motorcycles)

remove() ⽅法只删除第⼀个指定的值。如果要删除的值可能在列表中出现多次,就需要使⽤循环,确保将每个值都删
除。

cars = ['bmw', 'audi', 'toyota', 'subaru']
cars.sort()
#还可以按与字⺟顺序相反的顺序排列列表元素
cars.sort(reverse=True)
print(cars)

使⽤ sorted() 函数对列表进⾏临时排序:
在调⽤ sorted() 函数后,列表元素的排列顺序并没有变。如果要按与字⺟顺序相反的顺序显⽰列表,也可向 sorted() 函数传递参数 reverse=True

cars = ['bmw', 'audi', 'toyota', 'subaru']
print("Here is the original list:")
print(cars)
print("\nHere is the sorted list:")
print(sorted(cars))
print("\nHere is the original list again:")
print(cars)

反向打印列表:
要反转列表元素的排列顺序,可使⽤ reverse() ⽅法。
reverse() ⽅法会永久地修改列表元素的排列顺序,但可随时恢复到原来的排列顺序,只需对列表再次调⽤ reverse() 即可

cars = ['bmw', 'audi', 'toyota', 'subaru']
print(cars)
cars.reverse()
print(cars)

确定列表的⻓度:
使⽤ len() 函数可快速获悉列表的⻓度。

>>> cars = ['bmw', 'audi', 'toyota', 'subaru']
>>> len(cars)
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
 print(magician)
for value in range(1, 5):
 print(value)

range() 函数让 Python 从指定的第⼀个值开始数,并在到达指定的第⼆个值时停⽌,因此输出不包含第⼆个值(这⾥为 5)。
在调⽤ range() 函数时,也可只指定⼀个参数,这样它将从 0 开始,例
如,range(6) 返回数 0〜5(含)。

在使⽤ range() 函数时,还可指定步⻓。为此,可以给这个函数指定第三个参数,Python 将根据这个步⻓来⽣成数

even_numbers = list(range(2, 11, 2))
print(even_numbers)

使⽤ range() 创建数值列表:

numbers = list(range(1, 6))
print(numbers)

要创建数值列表,可使⽤ list() 函数将 range() 的结果直接转换为列表

对数值列表执⾏简单的统计计算:

>>> digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
>>> min(digits)
>>> max(digits)
>>> sum(digits)

列表推导式:
将 for 循环和创建新元素的代码合并成⼀⾏,并⾃动追加新元素

squares = [value**2 for value in range(1, 11)]
print(squares)
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[0:3])

如果没有指定第⼀个索引,Python 将⾃动从列表开头开始。
要让切⽚终⽌于列表末尾,也可使⽤类似的语法。

players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[:4])
print(players[2:])
print(players[1:5:2])

可在表⽰切⽚的⽅括号内指定第三个值。这个值告诉 Python 在指定范围内每隔多少元素提取⼀个

复制列表:

 my_foods = ['pizza', 'falafel', 'carrot cake']
 friend_foods = my_foods[:]
 print("My favorite foods are:")
 print(my_foods)
 print("\nMy friend's favorite foods are:")
 print(friend_foods)

如果通过friend_foods = my_foods,不能得到两个列表,对其中的一个进行修改会反应到另一个列表

元组

Python将不能修改的值称为不可变的,⽽不可变的列表称为元组(tuple)

dimensions = (200, 50)
print(dimensions[0])
print(dimensions[1])

如果你要定义只包含⼀个元素的元组,必须在这个元素后⾯加上逗号。

my_t = (3,)

遍历元组中的所有值:

dimensions = (200, 50)
for dimension in dimensions:
 print(dimension)

修改元组变量

dimensions = (200, 50)
print("Original dimensions:")
for dimension in dimensions:
 print(dimension)
dimensions = (400, 100)
print("\nModified dimensions:")
for dimension in dimensions:
 print(dimension)

if语句

>>> requested_toppings = ['mushrooms', 'onions', 'pineapple']
>>> 'mushrooms' in requested_toppings
True
>>> 'pepperoni' in requested_toppings
False
age = 12
if age < 4:
 price = 0
elif age < 18:
 price = 25
elif age < 65:
 price = 40
elif age >= 65:
 price = 20
print(f"Your admission cost is ${price}.")
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?")

对于数值 0、空值 None、单引号空字符串 ''、双引号空字符串 ""、空列表 []、空元组 ()、空字典 {},Python 都会返回 False

字典

alien_0 = {'color': 'green', 'points': 5}
print(alien_0['color'])
print(alien_0['points'])
alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
alien_0['x_position'] = 0
alien_0['y_position'] = 25
print(alien_0)
alien_0 = {}
alien_0['color'] = 'green'
alien_0['points'] = 5
print(alien_0)
alien_0 = {'color': 'green'}
print(f"The alien is {alien_0['color']}.")
alien_0['color'] = 'yellow'
print(f"The alien is now {alien_0['color']}.")
 alien_0 = {'color': 'green', 'points': 5}
 print(alien_0)
  del alien_0['points']
 print(alien_0)

遍历所有的键值对:

user_0 = {
 'username': 'efermi',
 'first': 'enrico',
 'last': 'fermi',
 }
for key, value in user_0.items():
 print(f"\nKey: {key}")
 print(f"Value: {value}")

遍历字典中的所有键:

favorite_languages = {
 'jen': 'python',
 'sarah': 'c',
 'edward': 'rust',
 'phil': 'python',
 }
for name in favorite_languages.keys():
 print(name.title())
for name in favorite_languages:

在遍历字典时,会默认遍历所有的键

favorite_languages = {
 --snip--
 }
if 'erin' not in favorite_languages.keys():
 print("Erin, please take our poll!")

遍历字典中的所有值:

favorite_languages = {
 'jen': 'python',
 'sarah': 'c',
 'edward': 'rust',
 'phil': 'python',
 }
print("The following languages have been mentioned:")
for language in favorite_languages.values():
 print(language.title())

排列键列表的副本:

favorite_languages = {
 'jen': 'python',
 'sarah': 'c',
 'edward': 'rust',
 'phil': 'python',
 }
for name in sorted(favorite_languages.keys()):
 print(f"{name.title()}, thank you for taking the poll.")

集合(set)剔除重复项:

favorite_languages = {
 --snip--
 }
print("The following languages have been mentioned:")
for language in set(favorite_languages.values()):
 print(language.title())

可以使⽤⼀对花括号直接创建集合,并在其中⽤逗号分隔元素:

>>> languages = {'python', 'rust', 'python', 'c'}
>>> languages
{'rust', 'python', 'c'}

集合和字典很容易混淆,因为它们都是⽤⼀对花括号定义的。当花括号内没有键值对时,定义的很可能是集合。不同于列表和字典,集合不会以特定的顺序存储元素。

字典列表:

 alien_0 = {'color': 'green', 'points': 5}
 alien_1 = {'color': 'yellow', 'points': 10}
 alien_2 = {'color': 'red', 'points': 15}
 aliens = [alien_0, alien_1, alien_2]
 for alien in aliens:
   print(alien)

在字典中存储列表:

 # 存储顾客所点⽐萨的信息
 pizza = {
 'crust': 'thick',
 'toppings': ['mushrooms', 'extra cheese'],
 }
 # 概述顾客点的⽐萨
 print(f"You ordered a {pizza['crust']}-crust pizza "
 "with the following toppings:")
 for topping in pizza['toppings']:
 print(f"\t{topping}")

在字典中存储字典:

 # 存储顾客所点⽐萨的信息
 pizza = {
 'crust': 'thick',
 'toppings': ['mushrooms', 'extra cheese'],
 }
 # 概述顾客点的⽐萨
 print(f"You ordered a {pizza['crust']}-crust pizza "
 "with the following toppings:")
 for topping in pizza['toppings']:
 print(f"\t{topping}")

while 循环

current_number = 1
while current_number <= 5:
 print(current_number)
 current_number += 1
pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
print(pets)
while 'cat' in pets:
 pets.remove('cat')
print(pets)

函数

def greet_user(username):
 """显⽰简单的问候语"""
 print(f"Hello, {username.title()}!")
greet_user('jesse')

位置实参:

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

关键字实参:
关键字实参是传递给函数的名值对

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 知道各个值该被赋给哪个形参。
下⾯两个函数调⽤是等效的:

describe_pet(animal_type='hamster', pet_name='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()}.")
describe_pet(pet_name='willie')

当使⽤默认值时,必须在形参列表中先列出没有默认值的形参,再列出有默认值的形参。这让 Python 依然能够正确地解读位置实参。

print_models(unprinted_designs[:], completed_models)
def make_pizza(*toppings):
 """打印顾客点的所有配料"""
 print(toppings)
make_pizza('pepperoni')
make_pizza('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)

形参 **user_info 中的两个星号让 Python 创建⼀个名为 user_info 的字典,该字典包含函数收到的其他所有名值对。
你经常会看到形参名 **kwargs,它⽤于收集任意数量的关键字实参。

将函数存储在称为模块的独⽴⽂件中,再将模块导⼊(import)主程序。

导⼊整个模块:
只需编写⼀条 import 语句并在其中指定模块名,就可在程序中使⽤该模块中的所有函数

import module_name
module_name.function_name()

导⼊特定的函数:

from module_name import function_name
from module_name import function_0, function_1, function_2
from pizza import make_pizza
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

使⽤ as 给函数指定别名:
如果要导⼊的函数的名称太⻓或者可能与程序中既有的名称冲突,可指定简短⽽独⼀⽆⼆的别名(alias):函数的另⼀个名称,类似于外号。要给函数指定这种特殊的外号,需要在导⼊时这样做。

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

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)
print(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old.")

__init__()⽅法
是⼀个特殊⽅法,每当你根据 Dog 类创建新实例时,Python 都会⾃动运⾏
它。在这个⽅法的名称中,开头和末尾各有两个下划线,这是⼀种约定,
旨在避免 Python 默认⽅法与普通⽅法发⽣名称冲突。

修改属性:

继承:
 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)
my_leaf = ElectricCar('nissan', 'leaf', 2024)
print(my_leaf.get_descriptive_name())

在既有的类的基础上编写新类,通常要调⽤⽗类的 init() ⽅法。这
将初始化在⽗类的 init() ⽅法中定义的所有属性,从⽽让⼦类也可
以使⽤这些属性。

在创建⼦类时,⽗类必须包含在当前⽂件中,且位于⼦类前⾯。

从⼀个模块中导⼊一个或多个类:

from car import ElectricCar
from car import Car, ElectricCar

导⼊整个模块,再使⽤点号访问需要的类

import car
my_mustang = car.Car('ford', 'mustang', 2024)
print(my_mustang.get_descriptive_name())

导⼊模块中的所有类(不推荐这种导⼊⽅式)

from module_name import *

给类或模块使⽤别名:

from electric_car import ElectricCar as EC
import electric_car as ec

类名应采⽤驼峰命名法,即将类名中的每个单词的⾸字⺟都⼤写,并且不
使⽤下划线。实例名和模块名都采⽤全⼩写格式,并在单词之间加上下划
线。

可以使⽤空⾏来组织代码,但不宜过多。在类中,可以使⽤⼀个空⾏来分
隔⽅法;⽽在模块中,可以使⽤两个空⾏来分隔类。

当需要同时导⼊标准库中的模块和你编写的模块时,先编写导⼊标准库模
块的 import 语句,再添加⼀个空⾏,然后编写导⼊你⾃⼰编写的模块的
import 语句。

文件和异常

from pathlib import Path
path = Path('pi_digits.txt')
contents = path.read_text()
contents = contents.rstrip()
print(contents)

你可以使⽤ splitlines() ⽅法将冗⻓的字符串转换为⼀系列⾏

lines = contents.splitlines()

写入文件:

from pathlib import Path
path = Path('programming.txt')
path.write_text("I love programming.")

在读取⽂本⽂件时,Python 将其中的所有⽂本都解释为字符串。如果读取的是数,并且要将其作为数值使⽤,就必须使⽤ int()函数将其转换为整数,或者使⽤ float() 函数将其转换为浮点数。
Python 只能将字符串写⼊⽂本⽂件。如果要将数值数据存储到
⽂本⽂件中,必须先使⽤函数 str() 将其转换为字符串格式

异常:

try:
 print(5/0)
except ZeroDivisionError:
 print("You can't divide by zero!")

通过将可能引发错误的代码放在 try-except 代码块中,可提⾼程序抵御
错误的能⼒。因为错误是执⾏除法运算的代码⾏导致的,所以需要将它放
到 try-except 代码块中。这个⽰例还包含⼀个 else 代码块,只有 try
代码块成功执⾏才需要继续执⾏的代码,都应放到 else 代码块中。

 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)

要让程序静默失败,可像通常那样编写 try 代码块,但在 except 代码块中明确地告诉 Python 什么都不要做。Python 有⼀个 pass 语句,可在代码块中使⽤它来让 Python 什么都不做。

def count_words(path):
 """计算⼀个⽂件⼤致包含多少个单词"""
 try:
 --snip--
 except FileNotFoundError:
   pass
 else:
 --snip--

json.dumps() 系列化:

 from pathlib import Path
 import json
 numbers = [2, 3, 5, 7, 11, 13]
 path = Path('numbers.json')
 contents = json.dumps(numbers)
 path.write_text(contents)

json.loads 反序列化:

 from pathlib import Path
 import json
 path = Path('numbers.json')
 contents = path.read_text()
 numbers = json.loads(contents)
 print(numbers)

测试

 # 更新系统中安装的任何包
 python -m pip install --upgrade package_name
 # 命令安装众多的第三⽅包
 # --user,这个标志让 Python 只为当前⽤户安装指定的包
 python -m pip install --user package_name
# 将 pip 升级到最新版本
python.exe -m pip install --upgrade pip
# 安装 pytest
python -m pip install --user pytest

测试⽂件的名称很重要,必须以test_打头。当你让 pytest 运⾏测试时,它将查找以 test_打头的⽂件,并运⾏其中的所有测试。
测试函数必须以 test_ 打头。在测试过程中,pytest 将找出并运⾏所有以 test_ 打头的函数。

如果在执⾏命令 pytest 时没有指定任何参数,pytest 将运⾏它在当前⽬录中找到的所有测试。为了专注于⼀个测试⽂件,可将该测试⽂件的名称作为参数传递给 pytest。

pytest 
pytest test_survey.py

常用的断言语句:

测试类
夹具(fixture):
在测试中,夹具(fixture)可帮助我们搭建测试环境。这通常意味着创建供
多个测试使⽤的资源。在 pytest 中,要创建夹具,可编写⼀个使⽤装饰器 @pytest.fixture 装饰的函数。装饰器(decorator)是放在函数定义前⾯的指令。在运⾏函数前,Python 将该指令应⽤于函数,以修改函数代码的⾏为。

 import pytest
 from survey import AnonymousSurvey
 @pytest.fixture
 def language_survey():
   """⼀个可供所有测试函数使⽤的 AnonymousSurvey 实例"""
   question = "What language did you first learn to speak?"
   language_survey = AnonymousSurvey(question)
   return language_survey
 def test_store_single_response(language_survey):
   """测试单个答案会被妥善地存储"""
   language_survey.store_response('English')
   assert 'English' in language_survey.responses
 def test_store_three_responses(language_survey):
   """测试三个答案会被妥善地存储"""
   responses = ['English', 'Spanish', 'Mandarin']
   for response in responses:
     language_survey.store_response(response)
   for response in responses:
     assert response in language_survey.responses

当测试函数的⼀个形参与应⽤了装饰器@pytest.fixture 的函数(夹具)同名时,将⾃动运⾏夹具,并将夹具返回的值传递给测试函数。

上一篇下一篇

猜你喜欢

热点阅读