什么是脚本
Python 是一种“脚本语言”。脚本,对应的英文是:script。一般人看到script这个英文单词,或许想到的更多的是:电影的剧本,就是一段段的脚本,所组成的。电影剧本的脚本,决定了电影中的人和物,都做哪些事情,怎么做。而计算机中的脚本,决定了:计算机中的操作系统和各种软件工具,要做哪些事情,以及具体怎么做。
脚本 vs 程序
你可能想要了解脚本与一般程序的区别是什么。
脚本与一般程序的主要区别在于是否编译。相对于程序而言,脚本更加随性。写完了脚本,直接就可以在某种具有解释功能的环境中运行。(我们将会在本课学习如何写和运行 Python 脚本。)
而非脚本语言(编译语言),比如 C、Java 语言。我们需要通过编译(Compile)和链接(link)等步骤,生成可执行文件。然后通过可执行文件在计算机上运行。
脚本编写
欢迎学习这节关于脚本编写的课程!你将学习:
- Python 安装和环境设置
- 运行和修改 Python 脚本
- 与用户输入交互
- 处理异常
- 读写文件
- 导入本地、标准和第三方模块
- 在解释器中进行实验
安装 Python 3
我们将使用最新版 Python - Python 3。虽然 Python 2 在很多场合依然会用到,但是已经不再接受更新。为了与后续 Python 改进保持兼容,建议使用 Python 3。
为了完成这一步骤,你需要使用命令行。我们将详细介绍所有细节部分,因此如果你从未使用过命令行,也没关系!如果你想深入了解命令行,请参阅我们的 Shell 讲习班,详细了解 Unix Shell。
你的计算机上已经有 Python 吗?
Mac OS X 和 Linux 通常已经自带了一个版本号比较老的 Python 2,请不要对该 Python 做出任何修改或者删除,因为操作系统的部分组件依赖它,修改或者删除它可能会影响到操作系统的某些功能。但是单独安装 Python 3,也不会对系统有任何影响。
Windows 通常没有自带 Python,但是你可以在安装之前,先检查下系统是否安装了 Python。首先检查是否已经安装了 Python 3。
打开终端或命令行。在 Windows 上,进入命令提示符窗口的方式是转到运行…
(同时按下带有windows图标的win键
+字母r
),然后输入 cmd
并按下 Enter
键。
在新的终端或命令提示符窗口中,输入 python --version
或者 python3 --version
$ python --version
然后按下 Enter
键。
注意:这里的$
符号在这里只是一个提示,表示命令行的开始,它会自动显示在屏幕上。这不是命令的一部分。
系统可能会显示已安装的 Python 版本是 Python 2.7.9
。在这种情况下,表明你已经安装了 Python 2,你需要按照下面几个部分中的步骤操作,更新到 Python 3。
如果版本号以 3 开头,则表明你已经安装了 Python 3!请勿再次安装 Python!
此外,你可能会看到错误消息。暂时不用管该错误,直接尝试下面几个部分中的步骤。
方法 1:安装 Anaconda
对于数据分析学员,强烈建议采用这种 Python 安装方式。
如果你对数据科学方面的 Python 感兴趣,强烈建议安装 Anaconda,即使你已经在计算机上安装了 Python。如果你尚未设置计算机,请参阅我们的 Anaconda 和 Jupyter notebook 简短课程设置计算机。你将学习如何为这门课程设置环境,需要安装 Python 3.6、Jupyter Notebook、NumPy、pandas、Matplotlib 和 Seaborn。
Anaconda 包含大量专门针对数据科学的库和软件分发版本,某些库和软件比较难安装。同时,你可以很轻松地在计算机上设置不同的环境,以便在不同版本的 Python 和软件包之间快速切换!例如,如果你正在处理的某个项目需要 Python 3.6 以及不同的依赖项,那么 Anaconda 的环境管理功能可以提供帮助。上面给出链接的 Anaconda 和 Jupyter notebook 免费课程讲授了如何处理这类情形。
如果你的英语不是很熟练,你也可以在中文网站上搜索安装Anaconda的教程,比如这个知乎帖子
方法 2:安装 Python
对使用 Python 进行数据分析不感兴趣的学员建议采用此方法。
如果你对学习面向数据科学的 Python 不感兴趣,并且你的计算机尚未安装 Python 3,那么现在该安装 Python 3 了!请转到 Python 下载页面并找到适用于你的操作系统、以 3 开头的最新版本(例如 Python 3.5.2)。
对于 Windows 和 Mac,我们发现最简单的方法是直接从 Python 下载网站下载安装程序并运行。如果你使用的是 Linux,Python 下载页面提供了进行下载和编译的源代码。此外,你可以使用 APT 等安装工具安装 Python 3。
如果你使用的是 Windows 设备,确保在安装过程中选中 Add Python 3.5 to PATH
或 Add Python to environment variables
选项,这样可以确保从命令行提示符窗口中访问 Python。
如果你使用的是 Windows 设备,并且已经安装了 Python,但是未选中上述选项,则需要将 Python 添加到 PATH。这样的话,当你输入 python
时,可以告诉命令行运行 Python 3。如果你未选中上述选项,或者转到下一阶段时似乎不可行,请按照 Python 文档中的这些说明将 Python 添加到 PATH。
完成安装程序中的所有步骤操作或编译了源代码后,则安装完毕,你可以在自己的计算机上使用 Python 3 了!
运行 Python 脚本
运行 Python 脚本!!
- 下载在本页面底部给出链接的文件
first_script.py
(你可能需要右击它,并存储为文件),然后将该文件移到计算机上的相应目录下。如果你还没有为这门课程创建一个目录的话,可以乘机创建一个目录。 - 打开终端并使用 cd 命令转到包含所下载文件的目录。
- 现在你已经位于该文件所在的目录,可以运行该文件了,方法是输入
python first_script.py
,然后按下 Enter 键。
提示:文件下载后,_ 会变成- ,你可能需要改成python first-script.py
。
如果你看到终端输出了以下消息,则表明你成功地运行了脚本:
Congratulations on running this script!!
辅助材料
编程环境设置
配置 Python 编程环境
你已经看到我的设置,现在花时间在你自己的计算机上熟悉下界面。 下面是一些我们推荐的文本编辑器,你可以尝试一个看看。
对于 Mac:
对于 Windows:
对于 Linux:
设置好屏幕,打开文本编辑器、终端/命令行,并在网络浏览器中打开优达学城课堂,以便与你的 Python 脚本交互。调整显示器选项,找到你觉得最舒适的显示效果,并看看能否找到 tab-to-four-spaces 选项 - 该选项对于 Python 缩进来说非常有用。
修改 Python 脚本
自己编写脚本
在文本编辑器中打开全新的空文件,命名该文件并将其保存到放置 Python 课程文件的文件夹中。将以下代码放入该文件里。
how_many_snakes = 1
snake_string = """
Welcome to Python3!
____
/ . .\\
\ ---<
\ /
__________/ /
-=:___________/
<3, Juno
"""
print(snake_string * how_many_snakes)
在脚本中接受原始输入
我们可以使用内置函数 input
获取用户的原始输入,该函数接受一个可选字符串参数,用于指定在要求用户输入时向用户显示的消息。
name = input("Enter your name: ")
print("Hello there, {}!".format(name.title()))
这段代码提示用户输入姓名,然后在问候语中使用该输入。input
函数获取用户输入的任何内容并将其存储为字符串。如果你想将输入解析为字符串之外的其他类型,例如整数(如以下示例所示),需要用新的类型封装结果并从字符串转换为该类型。
num = int(input("Enter an integer"))
print("hello" * num)
我们还可以使用内置函数 eval
将用户输入解析为 Python 表达式。该函数会将字符串评估为一行 Python 代码。
result = eval(input("Enter an expression: "))
print(result)
如果用户输入 2 * 3
,输出为 6
练习:在脚本中接受原始输入
练习:生成消息
假设你是一名老师,需要向每位学生发一条消息,提醒他们未交的作业和分数是多少。你知道每名学生的姓名,没交的作业份数和分数,这些数据保存在了电子表格中,你只需将这些输入插入你想到的以下消息中即可:
Hi [insert student name],
This is a reminder that you have [insert number of missing assignments] assignments left to submit before you can graduate. Your current grade is [insert current grade] and can increase to [insert potential grade] if you submit all assignments before the due date.
你可以将此消息复制粘贴后发送给每位学生,并且每次手动插入相应的值。但是你要写一个程序来帮助你完成这一流程。
写一个完成以下操作的脚本:
- 请求用户输入三次。一次是名字列表,一次是未交作业数量列表,一次是分数列表。使用该输入创建
names
、assignments
和grades
列表。 - 使用循环为每个学生输出一条信息并包含正确的值。潜在分数是 2 乘以未交作业数加上当前分数。
下面是在终端内成功运行该脚本的示例。
错误和异常
-
当 Python 无法解析代码时,就会发生语法错误,因为我们没有遵守正确的 Python 语法。当你出现拼写错误或第一次开始学习 Python 时,可能会遇到这些错误。
-
当在程序执行期间出现意外情况时,就会发生异常,即使代码在语法上正确无误。Python 有不同类型的内置异常,你可以在错误消息中查看系统抛出了什么异常。
Try 语句
我们可以使用 try 语句处理异常。你可以使用 4 个子句(除了视频中显示的子句之外还有一个子句)。
try
:这是try
语句中的唯一必需子句。该块中的代码是 Python 在try
语句中首先运行的代码。except
:如果 Python 在运行try
块时遇到异常,它将跳到处理该异常的except
块。else
:如果 Python 在运行try
块时没有遇到异常,它将在运行try
块后运行该块中的代码。finally
:在 Python 离开此try
语句之前,在任何情形下它都将运行此finally
块中的代码,即使要结束程序,例如:如果 Python 在运行except
或else
块中的代码时遇到错误,在停止程序之前,依然会执行此finally
块。
指定异常
我们实际上可以指定要在 except
块中处理哪个错误,如下所示:
try:
# some code
except ValueError:
# some code
现在它会捕获 ValueError 异常,但是不会捕获其他异常。如果我们希望该处理程序处理多种异常,我们可以在 except
后面添加异常元组。
try:
# some code
except (ValueError, KeyboardInterrupt):
# some code
或者,如果我们希望根据异常执行不同的代码块,可以添加多个 except
块。
try:
# some code
except ValueError:
# some code
except KeyboardInterrupt:
# some code
练习解决方案:处理除以零的情形
def create_groups(items, num_groups):
try:
size = len(items) // num_groups
except ZeroDivisionError:
print("WARNING: Returning empty list. Please use a nonzero number.")
return []
else:
groups = []
for i in range(0, len(items), size):
groups.append(items[i:i + size])
return groups
finally:
print("{} groups returned.".format(num_groups))
print("Creating 6 groups...")
for group in create_groups(range(32), 6):
print(list(group))
print("\nCreating 0 groups...")
for group in create_groups(range(32), 0):
print(list(group))
修改上面的脚本以处理除以零错误。正确修改的话,应该会输出:
Creating 6 groups...
6 groups returned.
[0, 1, 2, 3, 4]
[5, 6, 7, 8, 9]
[10, 11, 12, 13, 14]
[15, 16, 17, 18, 19]
[20, 21, 22, 23, 24]
[25, 26, 27, 28, 29]
[30, 31]
Creating 0 groups...
WARNING: Returning empty list. Please use a nonzero number.
0 groups returned.
访问错误消息
在处理异常时,依然可以如下所示地访问其错误消息:
try:
# some code
except ZeroDivisionError as e:
# some code
print("ZeroDivisionError occurred: {}".format(e))
应该会输出如下所示的结果:
ZeroDivisionError occurred: division by zero
因此依然可以访问错误消息,即使已经处理异常以防止程序崩溃!
如果没有要处理的具体错误,依然可以如下所示地访问消息:
try:
# some code
except Exception as e:
# some code
print("Exception occurred: {}".format(e))
Exception
是所有内置异常的基础类。你可以在此处详细了解 Python 的异常。
读写文件
以下是如何在 Python 中读写文件的方式。
读取文件
f = open('my_path/my_file.txt', 'r')
file_data = f.read()
f.close()
- 首先使用内置函数
open
打开文件。需要文件路径字符串。open
函数会返回文件对象,它是一个 Python 对象,Python 通过该对象与文件本身交互。在此示例中,我们将此对象赋值给变量f
。 - 你可以在
open
函数中指定可选参数。参数之一是打开文件时采用的模式。在此示例中,我们使用r
,即只读模式。这实际上是模式参数的默认值。 - 使用
read
访问文件对象的内容。该read
方法会接受文件中包含的文本并放入字符串中。在此示例中,我们将该方法返回的字符串赋值给变量file_data
。 - 当我们处理完文件后,使用
close
方法释放该文件占用的系统资源。
写入文件
f = open('my_path/my_file.txt', 'w')
f.write("Hello there!")
f.close()
- 以写入 ('w') 模式打开文件。如果文件不存在,Python 将为你创建一个文件。如果以写入模式打开现有文件,该文件中之前包含的所有内容将被删除。如果你打算向现有文件添加内容,但是不删除其中的内容,可以使用附加 ('a') 模式,而不是写入模式。
- 使用 write 方法向文件中添加文本。
- 操作完毕后,关闭文件。
With
Python 提供了一个特殊的语法,该语法会在你使用完文件后自动关闭该文件。
with open('my_path/my_file.txt', 'r') as f:
file_data = f.read()
该 with
关键字使你能够打开文件,对文件执行操作,并在缩进代码(在此示例中是读取文件)执行之后自动关闭文件。现在,我们不需要调用 f.close() 了!你只能在此缩进块中访问文件对象 f。
导入本地脚本
我们实际上可以导入其他脚本中的 Python,如果你处理的是大型项目,需要将代码整理成多个文件并重复利用这些文件中的代码,则导入脚本很有用。如果你要导入的 Python 脚本与当前脚本位于同一个目录下,只需输入 import
,然后是文件名,无需扩展名 .py。
import useful_functions
Import
语句写在 Python 脚本的顶部,每个导入语句各占一行。该 import
语句会创建一个模块对象,叫做 useful_functions
。模块是包含定义和语句的 Python 文件。要访问导入模块中的对象,需要使用点记法。
import useful_functions
useful_functions.add_five([1, 2, 3, 4])
我们可以为导入模块添加别名,以使用不同的名称引用它。
import useful_functions as uf
uf.add_five([1, 2, 3, 4])
使用 if main
块
为了避免运行从其他脚本中作为模块导入的脚本中的可执行语句,将这些行包含在 if __name__ == "__main__"
块中。或者,将它们包含在函数 main() 中并在 if main
块中调用该函数。
每当我们运行此类脚本时,Python 实际上会为所有模块设置一个特殊的内置变量 __name__
。当我们运行脚本时,Python 会将此模块识别为主程序,并将此模块的 __name__
变量设为字符串 "__main__"
。对于该脚本中导入的任何模块,这个内置 __name__
变量会设为该模块的名称。因此,条件 if __name__ == "__main__"
会检查该模块是否为主程序。
尝试一下!
下面是我在上述视频中使用的代码。请在同一目录下创建这些脚本,并在终端里运行这些脚本!实验 if main
块并访问导入模块中的对象!
# demo.py
import useful_functions as uf
scores = [88, 92, 79, 93, 85]
mean = uf.mean(scores)
curved = uf.add_five(scores)
mean_c = uf.mean(curved)
print("Scores:", scores)
print("Original Mean:", mean, " New Mean:", mean_c)
print(__name__)
print(uf.__name__)
# useful_functions.py
def mean(num_list):
return sum(num_list) / len(num_list)
def add_five(num_list):
return [n + 5 for n in num_list]
def main():
print("Testing mean function")
n_list = [34, 44, 23, 46, 12, 24]
correct_mean = 30.5
assert(mean(n_list) == correct_mean)
print("Testing add_five function")
correct_list = [39, 49, 28, 51, 17, 29]
assert(add_five(n_list) == correct_list)
print("All tests passed!")
if __name__ == '__main__':
main()
标准库
你可以在 Python 一周模块博客中发现新的模块。
我们的推荐模块
Python 标准库包含大量模块!为了帮助你熟悉那些实用的模块,我们在下面筛选了一些我们推荐的 Python 标准库模块并解释为何我们喜欢使用它们!
csv
:对于读取 csv 文件来说非常便利collections
:常见数据类型的实用扩展,包括OrderedDict
、defaultdict
和namedtuple
random
:生成假随机数字,随机打乱序列并选择随机项string
:关于字符串的更多函数。此模块还包括实用的字母集合,例如string.digits
(包含所有字符都是有效数字的字符串)。re
:通过正则表达式在字符串中进行模式匹配math
:一些标准数学函数os
:与操作系统交互os.path
:os
的子模块,用于操纵路径名称sys
:直接使用 Python 解释器json
:适用于读写 json 文件(面向网络开发)
希望你能用上这些模块!
导入模块技巧
还有一些在不同情形下很有用的其他形式的 import
语句。
- 要从模块中导入单个函数或类:
from module_name import object_name
- 要从模块中导入多个单个对象:
from module_name import first_object, second_object
- 要重命名模块:
import module_name as new_name
- 要从模块中导入对象并重命名:
from module_name import object_name as new_name
- 要从模块中单个地导入所有对象(请勿这么做):
from module_name import *
- 如果你真的想使用模块中的所有对象,请使用标准导入 module_name 语句并使用点记法访问每个对象。
import module_name
模块、软件包和名称
为了更好地管理代码,Standard 标准库中的模块被拆分成了子模块并包含在软件包中。软件包是一个包含子模块的模块。子模块使用普通的点记法指定。
子模块的指定方式是软件包名称、点,然后是子模块名称。你可以如下所示地导入子模块。
import package_name.submodule_name
第三方库
独立开发者编写了成千上万的第三方库!你可以使用 pip 安装这些库。pip 是在 Python 3 中包含的软件包管理器,它是标准 Python 软件包管理器,但并不是唯一的管理器。另一个热门的管理器是 Anaconda,该管理器专门针对数据科学。
要使用 pip 安装软件包,在命令行中输入“pip install”,然后是软件包名称,如下所示:pip install package_name
。该命令会下载并安装该软件包,以便导入你的程序中。安装完毕后,你可以使用从标准库中导入模块时用到的相同语法导入第三方软件包。
使用 requirements.txt
文件
大型 Python 程序可能依赖于十几个第三方软件包。为了更轻松地分享这些程序,程序员经常会在叫做 requirements.txt 的文件中列出项目的依赖项。下面是一个 requirements.txt 文件示例。
beautifulsoup4==4.5.1
bs4==0.0.1
pytz==2016.7
requests==2.11.1
该文件的每行包含软件包名称和版本号。版本号是可选项,但是通常都会包含。不同版本的库之间可能变化不大,可能截然不同,因此有必要使用程序作者在写程序时用到的库版本。
你可以使用 pip 一次性安装项目的所有依赖项,方法是在命令行中输入 pip install -r requirements.txt
。
实用的第三方软件包
能够安装并导入第三方库很有用,但是要成为优秀的程序员,还需要知道有哪些库可以使用。大家通常通过在线推荐或同事介绍了解实用的新库。如果你是一名 Python 编程新手,可能没有很多同事,因此为了帮助你了解入门信息,下面是优达学城工程师很喜欢使用的软件包列表。(可能部分网站在国内网络中无法打开)
- IPython - 更好的交互式 Python 解释器
- requests - 提供易于使用的方法来发出网络请求。适用于访问网络 API。
- Flask - 一个小型框架,用于构建网络应用和 API。
- Django - 一个功能更丰富的网络应用构建框架。Django 尤其适合设计复杂、内容丰富的网络应用。
- Beautiful Soup - 用于解析 HTML 并从中提取信息。适合网页数据抽取。
- pytest - 扩展了 Python 的内置断言,并且是最具单元性的模块。
- PyYAML - 用于读写 YAML 文件。
- NumPy - 用于使用 Python 进行科学计算的最基本软件包。它包含一个强大的 N 维数组对象和实用的线性代数功能等。
- pandas - 包含高性能、数据结构和数据分析工具的库。尤其是,pandas 提供 dataframe!
- matplotlib - 二维绘制库,会生成达到发布标准的高品质图片,并且采用各种硬拷贝格式和交互式环境。
- ggplot - 另一种二维绘制库,基于 R's ggplot2 库。
- Pillow - Python 图片库可以向你的 Python 解释器添加图片处理功能。
- pyglet - 专门面向游戏开发的跨平台应用框架。
- Pygame - 用于编写游戏的一系列 Python 模块。
- pytz - Python 的世界时区定义。
在解释器中进行实验
通过在终端里输入 python
启动 python 交互式解释器。你可以接着输入内容,直接与 Python 交互。这是每次实验和尝试一段 Python 代码的很棒工具。只需输入 Python 代码,输出将出现在下一行。
>>> type(5.23)
<class 'float'>
在解释器中,提示符窗口中最后一行的值将自动输出。如果有多行代码需要输出值,依然需要使用 print。
如果你开始定义函数,你将在提示符窗口中看到变化,表示这是可以继续的行。在定义函数时,你需要自己添加缩进。
>>> def cylinder_volume(height, radius):
... pi = 3.14159
... return height * pi * radius ** 2
解释器的不足之处是修改代码比较麻烦。如果你在输入该函数时出现了拼写错误,或者忘记缩进函数的主体部分,无法使用鼠标将光标点到要点击的位置。需要使用箭头键在代码行中来回移动。有必要了解一些实用的快捷方式,例如移到一行的开头或结尾。
注意,我可以引用我在解释器中之前定义的任何对象!
>>> cylinder_volume(10, 3)
282.7431
一个实用技巧是在交互式提示符窗口中使用上下箭头键循环浏览最近的命令。这样可以重新运行或修改已经尝试的代码。
要退出 Python 交互式解释器,使用命令 exit()
或在 mac/linux 上按下 ctrl+D
,在 windows 上按下 ctrl+Z
,然后按下 Enter
键。
IPython
实际上有一个代替默认 python 交互式解释器的强大解释器 IPython,它具有很多其他功能。
- Tab 键补充完整
?
:关于对象的详细信息!
:执行系统 shell 命令- 语法突出显示
你可以在此处查看更多其他功能!
获取所需的信息
要想成为熟练的程序员,需要掌握大量知识。需要了解库、记住语法以及其他细节。此外,让这一切更具挑战的是,技术在不断革新,因为新的技巧和工具会不断出现。
对于编程新手来说,学习所有这些细节并及时获悉新的发展动态似乎是一项不可能完成的任务。的确是这样!具有多年经验的编程专业人士实际上并不是在脑中记下百科全书一样的知识,而是掌握了快速查找信息的技巧。
如何搜索
下面是高效网络搜索的一些技巧:
- 在查询时,尝试使用 Python 或要使用的库的名称作为第一个字词。这样会告诉搜索引擎优先显示与你要使用的工具明确相关的结果。
- 创建良好的搜索查询需要多次尝试。如果第一次尝试时没有找到有用的结果,再试一遍。
- 尝试使用在一开始搜索时发现的网页上发现的关键字,使搜索引擎在后续搜索中转到更好的资源。
- 复制粘贴错误消息作为搜索字词。这样会出现错误解释性信息和潜在原因。错误消息可能包括你所写的特定行号引用。只在搜索中包含这些信息之前的错误消息部分。
- 如果找不到问题答案,自己提出问题!StackOverflow 等社区有一些行为规则,如果你要加入该社区,必须了解这些规则,但是别因为这些规则而不愿意使用这些资源。
在线资源的优先级
虽然有很多关于编程的在线资源,但是并非所有资源都是同等水平的。下面的资源列表按照大致的可靠性顺序排序。
- Python 教程 - 这部分官方文档给出了 Python 的语法和标准库。它会举例讲解,并且采用的语言比主要文档的要浅显易懂。确保阅读该文档的 Python 3 版本!
- Python 语言和库参考资料 - 语言参考资料和库参考资料比教程更具技术性,但肯定是可靠的信息来源。当你越来越熟悉 Python 时,应该更频繁地使用这些资源。
- 第三方库文档 - 第三方库会在自己的网站上发布文档,通常发布于 https://readthedocs.org/ 。你可以根据文档质量判断第三方库的质量。如果开发者没有时间编写好的文档,很可能也没时间完善库。
- 非常专业的网站和博客 - 前面的资源都是主要资源,他们是编写相应代码的同一作者编写的文档。主要资源是最可靠的资源。次要资源也是非常宝贵的资源。次要资源比较麻烦的是需要判断资源的可信度。Doug Hellmann 等作者和 Eli Bendersky 等开发者的网站很棒。不出名作者的博客可能很棒,也可能很糟糕。
- StackOverflow - 这个问答网站有很多用户访问,因此很有可能有人之前提过相关的问题,并且有人回答了!但是,答案是大家自愿提供的,质量参差不齐。在将解决方案应用到你的程序中之前,始终先理解解决方案。如果答案只有一行,没有解释,则值得怀疑。你可以在此网站上查找关于你的问题的更多信息,或发现替代性搜索字词。
- Bug 跟踪器 - 有时候,你可能会遇到非常罕见的问题或者非常新的问题,没有人在 StackOverflow 上提过。例如,你可能会在 GitHub 上的 bug 报告中找到关于你的错误的信息。这些 bug 报告很有用,但是你可能需要自己开展一些工程方面的研究,才能解决问题。
- 随机网络论坛 - 有时候,搜索结果可能会生成一些自 2004 年左右就不再活跃的论坛。如果这些资源是唯一解决你的问题的资源,那么你应该重新思考下寻找解决方案的方式。