做百家好还是个人网站,2021建站,清远网站开发sohu,设计师网页设计目录
1、读取文件
1.1 读取文件的全部内容
1.2 相对路径和绝对路径
1.3 访问文件中的各行
1.4 使用文件中的内容
1.5 包含100万位的大型文件
1.6 圆周率中的生日
2、写入文件
2.1 写入一行
2.2 写入多行
3、异常
3.1 处理ZeroDivisionError 异常
3.2 使用try-exce…目录
1、读取文件
1.1 读取文件的全部内容
1.2 相对路径和绝对路径
1.3 访问文件中的各行
1.4 使用文件中的内容
1.5 包含100万位的大型文件
1.6 圆周率中的生日
2、写入文件
2.1 写入一行
2.2 写入多行
3、异常
3.1 处理ZeroDivisionError 异常
3.2 使用try-except代码块
3.3 使用异常避免崩溃
3.4 else代码块
3.5 处理FileNotFoundError异常
3.6 分析文本
3.7 使用多个文件
3.8 静默失败
3.9 决定报告哪些错误
3.10 count()求特定单词
4、存储系统
4.1 使用json.dumps() 和 json.loads()
4.2 保存和读取用户生成的数据
4.3 重构 1、读取文件
要使⽤⽂本⽂件中的信息⾸先需要将信息读取到内存中。既可以⼀次性 读取⽂件的全部内容也可以逐⾏读取。
1.1 读取文件的全部内容
要读取⽂件需要⼀个包含若⼲⾏⽂本的⽂件。下⾯来创建⼀个⽂件它 包含精确到⼩数点后 30 位的圆周率值且在⼩数点后每 10 位处换⾏ 3.1415926535 8979323846 2643383279
下⾯的程序打开并读取这个⽂件再将其内容显⽰到屏幕上 from pathlib import Path
❶ path Path(pi_digits.txt)
❷ contents path.read_text()print(contents)
要使⽤⽂件的内容需要将其路径告知 Python。路径path指的是⽂件或
⽂件夹在系统中的准确位置。Python 提供了 pathlib 模块让你能够更轻
松地在各种操作系统中处理⽂件和⽬录。提供特定功能的模块通常称为库 library。这就是这个模块被命名为 pathlib 的原因所在。 这⾥⾸先从 pathlib 模块导⼊ Path 类。Path 对象指向⼀个⽂件可⽤ 来做很多事情。例如让你在使⽤⽂件前核实它是否存在读取⽂件的内 容以及将新数据写⼊⽂件。这⾥创建了⼀个表⽰⽂件 pi_digits.txt 的 Path 对象并将其赋给了变量 path⻅❶。由于这个⽂件与当前编写 的 .py ⽂件位于同⼀个⽬录中因此 Path 只需要知道其⽂件名就能访问 它。 创建表⽰⽂件 pi_digits.txt 的 Path 对象后使⽤ read_text() ⽅法来读 取这个⽂件的全部内容⻅❷。read_text() 将该⽂件的全部内容作为 ⼀个字符串返回⽽我们将这个字符串赋给了变量 contents。在打印 contents 的值时将显⽰这个⽂本⽂件的全部内容
3.1415926535 8979323846 2643383279
相⽐于原始⽂件该输出唯⼀不同的地⽅是末尾多了⼀个空⾏。为何会多 出这个空⾏呢因为 read_text() 在到达⽂件末尾时会返回⼀个空字符 串⽽这个空字符串会被显⽰为⼀个空⾏。 要删除这个多出来的空⾏可对字符串变量 contents 调⽤ rstrip()
from pathlib import Path
path Path(pi_digits.txt)
contents path.read_text()
contents contents.rstrip()
print(contents)
Python ⽅法 rstrip() 能删除字符串末尾的空⽩。现在
输出与原始⽂件的内容完全⼀致了
3.1415926535 8979323846 2643383279
要在读取⽂件内容时删除末尾的换⾏符可在调⽤ read_text() 后直接
调⽤⽅法 rstrip()
contents path.read_text().rstrip()
1.2 相对路径和绝对路径
当将类似于 pi_digits.txt 这样的简单⽂件名传递给 Path 时Python 将在当 前执⾏的⽂件即 .py 程序⽂件所在的⽬录中查找。
根据你组织⽂件的⽅式有时可能要打开不在程序⽂件所属⽬录中的⽂ 件。例如你可能将程序⽂件存储在了⽂件夹 python_work 中并且在⽂件 夹 python_work 中创建了⼀个名为 text_files 的⽂件夹⽤于存储程序⽂件 要操作的⽂本⽂件。虽然⽂件夹 text_files 在⽂件夹 python_work 中但仅 向 Path 传递⽂件夹 text_files 中的⽂件的名称也是不可⾏的因为 Python 只在⽂件夹 python_work 中查找⽽不会在其⼦⽂件夹 text_files 中查找。 要让 Python 打开不与程序⽂件位于同⼀个⽬录中的⽂件需要提供正确的 路径。
在编程中指定路径的⽅式有两种。⾸先相对⽂件路径让 Python 到相对 于当前运⾏的程序所在⽬录的指定位置去查找。由于⽂件夹 text_files 位于 ⽂件夹 python_work 中因此需要创建⼀个以 text_files 打头并以⽂件名结 尾的路径如下所⽰
path Path(text_files/filename.txt)
其次可以将⽂件在计算机中的准确位置告诉 Python这样就不⽤管当前 运⾏的程序存储在什么地⽅了。这称为绝对⽂件路径。在相对路径⾏不通 时可使⽤绝对路径。假如 text_files 并不在⽂件夹 python_work 中则仅 向 Path 传递路径 text_files/filename.txt 是⾏不通的因为 Python 只在⽂件夹 python_work 中查找该位置。为了明确地指出希望 Python 到哪⾥去查找需要提供绝对路径。
绝对路径通常⽐相对路径⻓因为它们以系统的根⽂件夹为起点
path Path(/home/eric/data_files/text_files/filename.txt)
使⽤绝对路径可读取系统中任何地⽅的⽂件。就⽬前⽽⾔最简单的做 法是要么将数据⽂件存储在程序⽂件所在的⽬录中要么将其存储在程 序⽂件所在⽬录下的⼀个⽂件夹如 text_files中。
注意在显⽰⽂件路径时Windows 系统使⽤反斜杠\⽽不是斜杠 /。但是你在代码中应该始终使⽤斜杠即便在 Windows 系统中
也是如此。在与你或其他⽤户的系统交互时pathlib 库会⾃动使⽤
正确的路径表⽰⽅法。
1.3 访问文件中的各行
你可以使⽤ splitlines() ⽅法将冗⻓的字符串转换为⼀系列⾏再使⽤ for 循环以每次⼀⾏的⽅式检查⽂件中的各⾏
from pathlib import Pathpath Path(pi_digits.txt)
❶ contents path.read_text()
❷ lines contents.splitlines()for line in lines:print(line)
1.4 使用文件中的内容
将⽂件的内容读取到内存中后就能以任意⽅式使⽤这些数据了。
from pathlib import Pathpath Path(pi_digits.txt)contents path.read_text()lines contents.splitlines()pi_string
❶ for line in lines:pi_string lineprint(pi_string)print(len(pi_string))
变量 pi_string 存储的字符串包含原来位于每⾏左端的空格。要删除这 些空格可对每⾏调⽤ lstrip()
--snip--
for line in lines:
pi_string line.lstrip()
print(pi_string)
print(len(pi_string))
注意在读取⽂本⽂件时Python 将其中的所有⽂本都解释为字符 串。如果读取的是数并且要将其作为数值使⽤就必须使⽤ int() 函数将其转换为整数或者使⽤ float() 函数将其转换为浮点数。
1.5 包含100万位的大型文件
如果⼀个⽂本⽂件包含精确到⼩数点后 1 000 000 位⽽不是 30 位的圆周率值也可以创建⼀个包含所有这些数字的字符串。⽆须对前⾯的程序做任何修改只需将这个⽂件传递给它即可。在这⾥ 只打印到⼩数点后 50 位以免终端花太多时间滚动显⽰全部的 1 000 000 位数字
from pathlib import Path
path Path(pi_million_digits.txt)
contents path.read_text()
lines contents.splitlines()
pi_string
for line in lines:pi_string line.lstrip()
print(f{pi_string[:52]}...)
print(len(pi_string))
输出表明创建的字符串确实包含精确到⼩数点后 1 000 000 位的圆周率
值
3.14159265358979323846264338327950288419716939937510...
1000002
在可处理的数据量⽅⾯Python 没有任何限制。只要系统的内存⾜够⼤ 你想处理多少数据就可以处理多少数据。 1.6 圆周率中的生日
我⼀直想知道⾃⼰的⽣⽇是否包含在圆周率值中。下⾯来扩展刚才编写的 程序以确定某个⼈的⽣⽇是否包含在圆周率值的前 1 000 000 位中。。为此可先将⽣⽇表⽰为⼀个由数字组成的字符串再检查这个字符串是否 在 pi_string 中
--snip--
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 million digits of pi!)
else:
print(Your birthday does not appear in the first million digits of
pi.)
⾸先提⽰⽤户输⼊其⽣⽇再检查这个字符串是否在 pi_string 中。运 ⾏这个程序
Enter your birthdate, in the form mmddyy: 120372
Your birthday appears in the first million digits of pi!
我的⽣⽇确实出现在了圆周率值中读取⽂件的内 容后就能以任意⽅式
对其进⾏分析了 2、写入文件
保存数据的最简单的⽅式之⼀是将其写⼊⽂件。
2.1 写入一行
定义⼀个⽂件的路径后就可使⽤ write_text() 将数据写⼊该⽂件了。
from pathlib import Path
path Path(programming.txt)
path.write_text(I love programming.)
write_text() ⽅法接受单个实参即要写⼊⽂件的字符串。
注意Python 只能将字符串写⼊⽂本⽂件。如果要将数值数据存储到
⽂本⽂件中必须先使⽤函数 str() 将其转换为字符串格式。
2.2 写入多行
write_text() ⽅法会在幕后完成⼏项⼯作。⾸先如果 path 变量对应 的路径指向的⽂件不存在就创建它。其次将字符串写⼊⽂件后它会 确保⽂件得以妥善地关闭。
要将多⾏写⼊⽂件需要先创建⼀个字符串其中包含要写⼊⽂件的全部 内容再调⽤ write_text() 并将这个字符串传递给它。
下⾯将多⾏内 容写⼊⽂件 programming.txt
from pathlib import Path
contents I love programming.\n
contents I love creating new games.\n
contents I also love working with data.\n
path Path(programming.txt)
path.write_text(contents)
⾸先定义变量 contents⽤于存储要写⼊⽂件的所有内容。
注意在对 path 对象调⽤ write_text() ⽅法时务必谨慎。如果 指定的⽂件已存在 write_text() 将删除其内容并将指定的内容写⼊其中。
3、异常
Python 使⽤称为异常exception的特殊对象来管理程序执⾏期间发⽣的 错误。每当发⽣让 Python 不知所措的错误时它都会创建⼀个异常对象。
如果你编写了处理该异常的代码程序将继续运⾏如果你未对异常进⾏ 理程序将停⽌并显⽰⼀个 traceback其中包含有关异常的报告。
异常是使⽤ try-except 代码块处理的。
3.1 处理ZeroDivisionError 异常
下⾯来看⼀种导致 Python 引发异常的简单错误。
print(5/0) Python ⽆法这样做因此你将看到⼀个 traceback
Traceback (most recent call last):File division_calculator.py, line 1, in moduleprint(5/0)~^~
❶ ZeroDivisionError: division by zero
在上述 traceback 中错误 ZeroDivisionError 是个异常对象⻅ ❶。Python 在⽆法按你的要求做时就会创建这种对象。在这种情况 下Python 将停⽌运⾏程序并指出引发了哪种异常⽽我们可根据这些 信息对程序进⾏修改。 3.2 使用try-except代码块
当你认为可能发⽣错误时可编写⼀个 try-except 代码块来处理可能引 发的异常。
try:print(5/0)
except ZeroDivisionError:print(You cant divide by zero!)
3.3 使用异常避免崩溃
如果在错误发⽣时程序还有⼯作没有完成妥善地处理错误就显得尤其 重要。 print(Give me two numbers, and Ill divide them.)print(Enter q to quit.)while True:first_number input(\nFirst number: )if first_number q:breaksecond_number input(Second number: )if second_number q:breakanswer int(first_number) / int(second_number)print(answer)
这个 程序没有采取任何处理错误的措施因此在执⾏除数为 0 的除法运算时
它将崩溃
Give me two numbers, and Ill divide them.
Enter q to quit.
First number: 5
Second number: 0
Traceback (most recent call last): File division_calculator.py, line 11, in module answer int(first_number) / int(second_number) ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
ZeroDivisionError: division by zero
程序崩溃可不好让⽤户看到 traceback 也不是个好主意。不懂技术的⽤户 会感到糊涂怀有恶意的⽤户还能通过 traceback 获悉你不想让他们知道的 信息。
3.4 else代码块
通过将可能引发错误的代码放在 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 cant divide by 0!)
❸else: print(answer)
3.5 处理FileNotFoundError异常
在使⽤⽂件时⼀种常⻅的问题是找不到⽂件要查找的⽂件可能在其他 地⽅⽂件名可能不正确或者这个⽂件根本就不存在。 我们来尝试读取⼀个不存在的⽂件。下⾯的程序尝试读取⽂件 alice.txt 的内
容但这个⽂件并没有被存储在 alice.py 所在的⽬录中
from pathlib import Path
path Path(alice.txt)
contents path.read_text(encodingutf-8)
请注意这⾥使⽤ read_text() 的⽅式与前⾯稍有不同。如果系统的默 认编码与要读取的⽂件的编码不⼀致参数 encoding 必不可少。如果要 读取的⽂件不是在你的系统中创建的这种情况更容易发⽣。
Python ⽆法读取不存在的⽂件因此引发了⼀个异常 Traceback (most recent call last):
❶ File alice.py, line 4, in module
❷ contents path.read_text(encodingutf-8) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File /.../pathlib.py, line 1056, in read_text with self.open(moder, encodingencoding, errorserrors) as f: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File /.../pathlib.py, line 1042, in open return io.open(self, mode, buffering, encoding, errors, newline) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ❸ FileNotFoundError: [Errno 2] No such file or directory: alice.txt
这⾥的 traceback ⽐前⾯的那些都⻓因此下⾯介绍如何看懂复杂的 traceback。
通常最好从 traceback 的末尾着⼿。
从最后⼀⾏可知引发了异 常 FileNotFoundError⻅❸。这⼀点很重要它让我们知道应该在 要编写的 except 代码块中使⽤哪种异常。
回头看看 traceback 开头附近⻅❶从这⾥可知错误发⽣在⽂件 alice.py 的第四⾏。接下来的⼀⾏列出了导致错误的代码⾏⻅❷。 traceback 的其余部分列出了⼀些代码它们来⾃打开和读取⽂件涉及的 库。通常不需要详细阅读和理解 traceback 中的这些内容。
为了处理这个异常应将 traceback 指出的存在问题的代码⾏放到 try 代码
块中。这⾥存在问题的是包含 read_text() 的代码⾏
from pathlib import Pathpath Path(alice.txt)try:contents path.read_text(encodingutf-8)
❶ except FileNotFoundError:print(fSorry, the file {path} does not exist.)
这样当找不 到⽂件时Python 将运⾏ except 代码块中的代码从⽽显⽰⼀条友好的
错误消息⽽不是 traceback
Sorry, the file alice.txt does not exist.
3.6 分析文本
你可以分析包含整本书的⽂本⽂件。
下⾯来提取童话 Alice in Wonderland《爱丽丝漫游奇境记》的⽂本并 尝试计算它包含多少个单词。我们将使⽤ split() ⽅法它默认以空⽩为 分隔符将字符串分拆成多个部分
from pathlib import Path
path Path(alice.txt)
try:contents path.read_text(encodingutf-8)
except FileNotFoundError:print(fSorry, the file {path} does not exist.)
else:
#计算⽂件⼤致包含多少个单词
❶ words contents.split()
❷ num_words len(words)
print(fThe file {path} has about {num_words} words.)
我将⽂件 alice.txt 移到了正确的⽬录中让 try 代码块能够成功地执⾏。 对变量 contents它现在是⼀个⻓⻓的字符串包含童话 Alice in Wonderland 的全部⽂本调⽤ split() ⽅法⽣成⼀个列表其中包含这 部童话中的所有单词⻅❶。 3.7 使用多个文件
下⾯多分析⼏本书。先将这个程序的⼤部分代码移到⼀个名为 count_words() 的函数中这样对多本书进⾏分析会更容易 from pathlib import Pathdef count_words(path):
❶ 计算⼀个⽂件⼤致包含多少个单词try:contents path.read_text(encodingutf-8)except FileNotFoundError:print(fSorry, the file {path} does not exist.)else:# 计算⽂件⼤致包含多少个单词words contents.split()num_words len(words)print(fThe file {path} has about {num_words} words.)path Path(alice.txt)count_words(path)
这些代码⼤多与原来⼀样只是被移到了函数 count_words() 中并且 增加了缩进量。
为此我们把要分析的⽂件的名称存储在⼀个列表中然后对列表中 的每个⽂件都调⽤ count_words()。 from pathlib import Pathdef count_words(filename):--snip--filenames [alice.txt, siddhartha.txt, moby_dick.txt, little_women.txt]for filename in filenames:
❶ path Path(filename)count_words(path)
3.8 静默失败
我们告诉⽤户有⼀个⽂件找不到。但并⾮每次捕获异常 都需要告诉⽤户你有时候希望程序在发⽣异常时保持静默就像什么都 没有发⽣⼀样继续运⾏。要让程序静默失败可像通常那样编写 try 代码 块但在 except 代码块中明确地告诉 Python 什么都不要做。Python 有⼀ 个 pass 语句可在代码块中使⽤它来让 Python 什么都不做
def count_words(path):计算⼀个⽂件⼤致包含多少个单词try:--snip--except FileNotFoundError:passelse:--snip--
现在当出现 FileNotFoundError 异常时虽然仍将执⾏except 代码块中的代码但什么都不会发⽣。 3.9 决定报告哪些错误
如果⽤ 户知道要分析哪些⽂件他们可能希望在有⽂件未被分析时出现⼀条消息
来告知原因。
如果⽤户只想看到结果并不知道要分析哪些⽂件可能就 ⽆须在有些⽂件不存在时告知他们。 3.10 count()求特定单词
可以使⽤⽅法 count() 来确定特定的单词或短语在字符串中出现了多
少次。例如下⾯的代码计算 row 在⼀个字符串中出现了多少次 line Row, row, row your boat line.count(row)
2 line.lower().count(row)
3
请注意通过使⽤ lower() 将字符串转换为全⼩写的可捕捉要查找 的单词的各种格式⽽不管其⼤⼩写如何。 4、存储系统
很多程序要求⽤户输⼊某种信息⽐如让⽤户存储游戏⾸选项或提供要可 视化的数据。当⽤户关闭程序时⼏乎总是要保存他们提供的信 息。⼀种简单的⽅式是使⽤模块 json 来存储数据。
模块 json 让你能够将简单的 Python 数据结构转换为 JSON 格式的字符 串并在程序再次运⾏时从⽂件中加载数据。你还可以使⽤ json 在 Python 程序之间共享数据。
注意JSONJavaScript Object Notation格式最初是为 JavaScript 开发 的但随后成了⼀种通⽤的格式被包括 Python 在内的众多语⾔采 ⽤。
4.1 使用json.dumps() 和 json.loads()
下⾯先编写⼀个存储⼀组数的简短程序再编写⼀个将这些数读取到内存 中的程序。第⼀个程序将使⽤ json.dumps() 来存储这组数⽽第⼆个程 序将使⽤ json.loads() 来读取它们。
json.dumps() 函数接受⼀个实参即要转换为 JSON 格式的数据。这个 函数返回⼀个字符串这样你就可将其写⼊数据⽂件了 from pathlib import Pathimport jsonnumbers [2, 3, 5, 7, 11, 13]
❶ path Path(numbers.json)
❷ contents json.dumps(numbers)path.write_text(contents)
下⾯再编写⼀个程序使⽤ json.loads() 将这个列表读取到内存中 from pathlib import Pathimport json
❶ path Path(numbers.json)
❷ contents path.read_text()
❸ numbers json.loads(contents)print(numbers)
在❶处确保读取的是前⾯写⼊的⽂件。这个数据⽂件是使⽤特殊格式的 ⽂本⽂件因此可使⽤ read_text() ⽅法来读取它⻅❷。然后将这 个⽂件的内容传递给 json.loads()⻅❸。这个函数将⼀个 JSON 格 式的字符串作为参数并返回⼀个 Python 对象这⾥是⼀个列表⽽我 们将这个对象赋给了变量 numbers。最后打印恢复的数值列表看看是 否与 number_writer.py 中创建的数值列表相同
[2, 3, 5, 7, 11, 13]
这是⼀种在程序之间共享数据的简单⽅式。 4.2 保存和读取用户生成的数据
使⽤ json 保存⽤户⽣成的数据很有必要因为如果不以某种⽅式进⾏存 储⽤户的信息就会在程序停⽌运⾏时丢失。
下⾯来看⼀个这样的例⼦
提⽰⽤户在⾸次运⾏程序时输⼊⾃⼰的名字并且在他再次运⾏程序时仍
然记得他。
先来存储⽤户的名字 from pathlib import Path import json
❶ username input(What is your name? )
❷ path Path(username.json) contents json.dumps(username) path.write_text(contents)
❸ print(fWell remember you when you come back, {username}!)
⾸先提⽰⽤户输⼊名字⻅❶。接下来将收集到的数据写⼊⽂件 username.json⻅❷。然后打印⼀条消息指出存储了⽤户输⼊的信息 ⻅❸
What is your name? Eric
Well remember you when you come back, Eric!
现在再编写⼀个程序向名字已被存储的⽤户发出问候
greet_user.py
from pathlib import Path import json
❶ path Path(username.json) contents path.read_text()
❷ username json.loads(contents)
print(fWelcome back, {username}!) 我们读取数据⽂件的内容⻅❶并使⽤json.loads() 将恢复的数据 赋给变量 username⻅❷。有了已恢复的⽤户名就可以使⽤个性化 的问候语欢迎⽤户回来了
Welcome back, Eric! 需要将这两个程序合并到⼀个程序remember_me.py中。在这个程序运 ⾏时将尝试从内存中获取⽤户的⽤户名。如果没有找到就提⽰⽤户输 ⼊⽤户名并将其存储到⽂件 username.json 中以供下次使⽤。 from pathlib import Pathimport jsonpath Path(username.json)
❶ if path.exists():contents path.read_text()username json.loads(contents)print(fWelcome back, {username}!)
❷ else:username input(What is your name? )contents json.dumps(username)path.write_text(contents)print(fWell remember you when you come back, {username}!)
4.3 重构
你经常会遇到这样的情况虽然代码能够正确地运⾏但还可以将其划分 为⼀系列完成具体⼯作的函数来进⾏改进。这样的过程称为重构。
要重构 remember_me.py可将其⼤部分逻辑放到⼀个或多个函数中。
remember_me.py 的重点是问候⽤户因此将其所有代码都放到⼀个名为
greet_user() 的函数中 from pathlib import Path import json
def greet_user():
❶问候⽤户并指出其名字 path Path(username.json) if path.exists(): contents path.read_text() username json.loads(contents) print(fWelcome back, {username}!) else: username input(What is your name? ) contents json.dumps(username) path.write_text(contents) print(fWell remember you when you come back, {username}!)
greet_user()
下⾯重构 greet_user()不让它执⾏这么多任务。⾸先将获取已存储⽤
户名的代码移到另⼀个函数中
from pathlib import Path
import jsondef get_stored_username(path):
❶如果存储了⽤户名就获取它 if path.exists(): contents path.read_text() username json.loads(contents)
return username
else:
❷return None def greet_user(): 问候⽤户并指出其名字 path Path(username.json)
username get_stored_username(path)
❸if username: print(fWelcome back, {username}!) else: username input(What is your name? ) contents json.dumps(username) path.write_text(contents) print(fWell remember you when you come back, {username}!) greet_user()
新增的 get_stored_username() 函数⽬标明确⽂档字符串⻅❶ 指出了这⼀点。
还需要将 greet_user() 中的另⼀个代码块提取出来将在没有存储⽤户名时提⽰⽤户输⼊的代码放在⼀个独⽴的函数中 from pathlib import Pathimport jsondef get_stored_username(path):如果存储了⽤户名就获取它--snip--def get_new_username(path):提⽰⽤户输⼊⽤户名username input(What is your name? )contents json.dumps(username)path.write_text(contents)return usernamedef greet_user():问候⽤户并指出其名字path Path(username.json)
❶ username get_stored_username(path)if username:print(fWelcome back, {username}!)else:
❷ username get_new_username(path)print(fWell remember you when you come back, {username}!)greet_user()
在 remember_me.py 的这个最终版本中每个函数都执⾏单⼀⽽清晰的任 务。我们调⽤ greet_user()它打印⼀条合适的消息要么欢迎⽼⽤户 回来要么问候新⽤户。