Python 物联网入门指南(五)(1)https://developer.aliyun.com/article/1507233
Python 实用程序
Python 带有几个实用程序,可以与其他文件和操作系统本身进行交互。我们已经确定了我们在过去项目中使用过的所有这些 Python 实用程序。让我们讨论不同的模块及其用途,因为我们可能会在本书的最终项目中使用它们。
os 模块
正如其名称所示,这个模块(docs.python.org/3.1/library/os.html
)可以与操作系统进行交互。让我们通过示例讨论一些应用。
检查文件是否存在
os
模块可用于检查特定目录中是否存在文件。例如:我们广泛使用了write_file.txt
文件。在打开此文件进行读取或写入之前,我们可以检查文件是否存在:
import os if __name__ == "__main__": # Check if file exists if os.path.isfile('/home/pi/Desktop/code_samples/write_file.txt'): print('The file exists!') else: print('The file does not exist!')
在上述代码片段中,我们使用了os.path
模块中提供的isfile()
函数。当文件位置作为函数的参数传递时,如果文件存在于该位置,则返回True
。在这个例子中,由于文件write_file.txt
存在于代码示例目录中,该函数返回True
。因此屏幕上打印出消息文件存在
:
if os.path.isfile('/home/pi/Desktop/code_samples/write_file.txt'): print('The file exists!') else: print('The file does not exist!')
检查文件夹是否存在
与os.path.isfile()
类似,还有另一个名为os.path.isdir()
的函数。如果特定位置存在文件夹,则返回True
。我们一直在查看位于树莓派桌面上的名为code_samples
的文件夹中的所有代码示例。可以通过以下方式确认其存在:
# Confirm code_samples' existence if os.path.isdir('/home/pi/Desktop/code_samples'): print('The directory exists!') else: print('The directory does not exist!')
删除文件
os
模块还可以使用remove()
函数删除文件。将任何文件作为函数的参数传递即可删除该文件。在文件 I/O部分,我们讨论了使用文本文件read_file.txt
从文件中读取。让我们通过将其作为remove()
函数的参数来删除该文件:
os.remove('/home/pi/Desktop/code_samples/read_file.txt')
终止进程
可以通过将进程pid
传递给kill()
函数来终止在树莓派上运行的应用程序。在上一章中,我们讨论了在树莓派上作为后台进程运行的light_scheduler
示例。为了演示终止进程,我们将尝试终止该进程。我们需要确定light_scheduler
进程的进程pid
(您可以选择由您作为用户启动的应用程序,不要触及根进程)。可以使用以下命令从命令行终端检索进程pid
:
ps aux
它会显示当前在树莓派上运行的进程(如下图所示)。light_scheduler
应用程序的进程pid
为 1815:
light_scheduler 守护程序的 PID
假设我们知道需要终止的应用程序的进程pid
,让我们回顾使用kill()
函数终止该函数。终止函数所需的参数包括进程pid
和需要发送到进程以终止应用程序的信号(signal.SIGKILL
):
import os import signal if __name__ == "__main__": #kill the application try: os.kill(1815, signal.SIGKILL) except OSError as error: print("OS Error " + str(error))
signal
模块(docs.python.org/3/library/signal.html)
)包含表示可用于停止应用程序的信号的常量。在此代码片段中,我们使用了SIGKILL
信号。尝试运行ps
命令(ps aux
),您会注意到light_scheduler
应用程序已被终止。
监控一个进程
在前面的示例中,我们讨论了使用kill()
函数终止应用程序。您可能已经注意到,我们使用了称为try
/except
关键字来尝试终止应用程序。我们将在下一章详细讨论这些关键字。
还可以使用try
/except
关键字使用kill()
函数来监视应用程序是否正在运行。在介绍使用try
/except
关键字捕获异常的概念后,我们将讨论使用kill()
函数监视进程。
os
模块中讨论的所有示例都可以与本章一起下载,文件名为os_utils.py
。
glob 模块
glob
模块(docs.python.org/3/library/glob.html
)使得能够识别具有特定扩展名或特定模式的文件。例如,可以列出文件夹中的所有 Python 文件如下:
# List all files for file in glob.glob('*.py'): print(file)
glob()
函数返回一个包含.py
扩展名的文件列表。使用for
循环来遍历列表并打印每个文件。当执行前面的代码片段时,输出包含属于本章的所有代码示例的列表(输出被截断以表示):
read_from_file.py config_parser_read.py append_to_file.py read_line_from_file.py config_parser_modify.py python_utils.py config_parser_write.py csv_write.py
这个模块在列出具有特定模式的文件时特别有帮助。例如:让我们考虑这样一个场景,您想要上传来自实验不同试验的文件。您只对以下格式的文件感兴趣:file1xx.txt
,其中x
代表0
到9
之间的任意数字。这些文件可以按以下方式排序和列出:
# List all files of the format 1xx.txt for file in glob.glob('txt_files/file1[0-9][0-9].txt'): print(file)
在前面的示例中,[0-9]
表示文件名可以包含0
到9
之间的任意数字。由于我们正在寻找file1xx.txt
格式的文件,因此作为参数传递给glob()
函数的搜索模式是file1[0-9][0-9].txt
。
当执行前面的代码片段时,输出包含指定格式的所有文本文件:
txt_files/file126.txt txt_files/file125.txt txt_files/file124.txt txt_files/file123.txt txt_files/file127.txt
我们找到了一篇解释使用表达式对文件进行排序的文章:www.linuxjournal.com/content/bash-extended-globbing
。相同的概念可以扩展到使用glob
模块搜索文件。
读者的挑战
使用glob
模块讨论的例子可以与本章一起下载,文件名为glob_example.py
。在其中一个例子中,我们讨论了列出特定格式的文件。你将如何列出以下格式的文件:filexxxx.*
?(这里的x
代表0
到9
之间的任意数字。*
代表任何文件扩展名。)
shutil 模块
shutil
模块(docs.python.org/3/library/shutil.html
)使得可以使用move()
和copy()
方法在文件夹之间移动和复制文件。在上一节中,我们列出了文件夹txt_files
中的所有文本文件。让我们使用move()
将这些文件移动到当前目录(代码执行的位置),再次在txt_files
中复制这些文件,最后从当前目录中删除这些文本文件:
import glob import shutil import os if __name__ == "__main__": # move files to the current directory for file in glob.glob('txt_files/file1[0-9][0-9].txt'): shutil.move(file, '.') # make a copy of files in the folder 'txt_files' and delete them for file in glob.glob('file1[0-9][0-9].txt'): shutil.copy(file, 'txt_files') os.remove(file)
在前面的例子中(可以与本章一起下载,文件名为shutil_example.py
),文件被移动和复制,源和目的地分别作为第一个和第二个参数指定。
使用glob
模块识别要移动(或复制)的文件,然后使用它们对应的方法移动或复制每个文件。
subprocess 模块
我们在上一章简要讨论了这个模块。subprocess
模块(docs.python.org/3.2/library/subprocess.html
)使得可以在 Python 程序内部启动另一个程序。subprocess
模块中常用的函数之一是Popen
。需要在程序内部启动的任何进程都需要作为列表参数传递给Popen
函数:
import subprocess if __name__ == "__main__": subprocess.Popen(['aplay', 'tone.wav'])
在前面的例子中,tone.wav
(需要播放的 WAVE 文件)和需要运行的命令作为列表参数传递给函数。subprocess
模块中还有其他几个类似用途的命令。我们留给你去探索。
sys 模块
sys
模块(docs.python.org/3/library/sys.html
)允许与 Python 运行时解释器进行交互。sys
模块的一个功能是解析作为程序输入提供的命令行参数。让我们编写一个程序,读取并打印作为程序参数传递的文件的内容:
import sys if __name__ == "__main__": with open(sys.argv[1], 'r') as read_file: print(read_file.read())
尝试按以下方式运行前面的例子:
python3 sys_example.py read_lines.txt
前面的例子可以与本章一起下载,文件名为sys_example.py
。在运行程序时传递的命令行参数列表可以在sys
模块的argv
列表中找到。argv[0]
通常是 Python 程序的名称,argv[1]
通常是传递给函数的第一个参数。
当以read_lines.txt
作为参数执行sys_example.py
时,程序应该打印文本文件的内容:
I am learning Python Programming using the Raspberry Pi Zero. This is the second line. Line 3. Line 4. Line 5. Line 6. Line 7.
总结
在本章中,我们讨论了文件 I/O - 读取和写入文件,以及用于读取、写入和追加文件的不同标志。我们谈到了将文件指针移动到文件的不同位置以检索特定内容或在特定位置覆盖文件内容。我们讨论了 Python 中的ConfigParser
模块及其在存储/检索应用程序配置参数以及读写 CSV 文件中的应用。
最后,我们讨论了在我们的项目中潜在使用的不同 Python 工具。我们将广泛使用文件 I/O 和在本书中讨论的 Python 工具。我们强烈建议在进入本书中讨论的最终项目之前,熟悉本章讨论的概念。
在接下来的章节中,我们将讨论将存储在 CSV 文件中的传感器数据上传到云端,以及记录应用程序执行过程中遇到的错误。下一章见!
第十五章:请求和 Web 框架
本章的主要内容是 Python 中的请求和 Web 框架。我们将讨论使得从 Web 检索数据(例如,获取天气更新)、将数据上传到远程服务器(例如,记录传感器数据)或控制本地网络上的设备成为可能的库和框架。我们还将讨论一些有助于学习本章核心主题的话题。
try
/except
关键字
到目前为止,我们已经审查并测试了所有的例子,假设程序的执行不会遇到错误。相反,应用程序有时会由于外部因素(如无效的用户输入和糟糕的互联网连接)或程序员造成的程序逻辑错误而失败。在这种情况下,我们希望程序报告/记录错误的性质,并在退出程序之前继续执行或清理资源。try
/except
关键字提供了一种机制,可以捕获程序执行过程中发生的错误并采取补救措施。由于可能在代码的关键部分捕获和记录错误,try
/except
关键字在调试应用程序时特别有用。
通过比较两个例子来理解try
/except
关键字。让我们构建一个简单的猜数字游戏,用户被要求猜一个 0 到 9 之间的数字:
- 使用 Python 的
random
模块生成一个随机数(在 0 到 9 之间)。如果用户猜测的数字正确,Python 程序会宣布用户为赢家并退出游戏。 - 如果用户输入是字母
x
,程序会退出游戏。 - 用户输入使用
int()
函数转换为整数。进行了一个合理性检查,以确定用户输入是否是 0 到 9 之间的数字。 - 整数与随机数进行比较。如果它们相同,程序会宣布用户为赢家并退出游戏。
让我们观察当我们故意向这个程序提供错误的输入时会发生什么(这里显示的代码片段可以在本章的下载中找到,文件名为guessing_game.py
):
import random if __name__ == "__main__": while True: # generate a random number between 0 and 9 rand_num = random.randrange(0,10) # prompt the user for a number value = input("Enter a number between 0 and 9: ") if value == 'x': print("Thanks for playing! Bye!") break input_value = int(value) if input_value < 0 or input_value > 9: print("Input invalid. Enter a number between 0 and 9.") if input_value == rand_num: print("Your guess is correct! You win!") break else: print("Nope! The random value was %s" % rand_num)
让我们执行前面的代码片段,并向程序提供输入hello
:
Enter a number between 0 and 9: hello Traceback (most recent call last): File "guessing_game.py", line 12, in <module> input_value = int(value) ValueError: invalid literal for int() with base 10: 'hello'
在前面的例子中,当程序试图将用户输入hello
转换为整数时失败。程序执行以异常结束。异常突出了发生错误的行。在这种情况下,它发生在第 10 行:
File "guessing_game.py", line 12, in <module> input_value = int(value)
异常的性质也在异常中得到了突出。在这个例子中,最后一行表明抛出的异常是ValueError
:
ValueError: invalid literal for int() with base 10: 'hello'
让我们讨论一个相同的例子(可以在本章的下载中找到,文件名为try_and_except.py
),它使用了try
/except
关键字。在捕获异常并将其打印到屏幕后,可以继续玩游戏。我们有以下代码:
import random if __name__ == "__main__": while True: # generate a random number between 0 and 9 rand_num = random.randrange(0,10) # prompt the user for a number value = input("Enter a number between 0 and 9: ") if value == 'x': print("Thanks for playing! Bye!") try: input_value = int(value) except ValueError as error: print("The value is invalid %s" % error) continue if input_value < 0 or input_value > 9: print("Input invalid. Enter a number between 0 and 9.") continue if input_value == rand_num: print("Your guess is correct! You win!") break else: print("Nope! The random value was %s" % rand_num)
让我们讨论相同的例子如何使用try
/except
关键字:
- 从前面的例子中,我们知道当用户提供错误的输入时(例如,一个字母而不是 0 到 9 之间的数字),异常发生在第 10 行(用户输入转换为整数的地方),错误的性质被命名为
ValueError
。 - 可以通过将其包装在
try...except
块中来避免程序执行的中断:
try: input_value = int(value) except ValueError as error: print("The value is invalid %s" % error)
- 在接收到用户输入时,程序会在
try
块下尝试将用户输入转换为整数。 - 如果发生了
ValueError
,except
块会捕获error
,并将以下消息与实际错误消息一起打印到屏幕上:
except ValueError as error: print("The value is invalid %s" % error)
- 尝试执行代码示例并提供无效输入。您会注意到程序打印了错误消息(以及错误的性质),然后返回游戏循环的顶部并继续寻找有效的用户输入:
Enter a number between 0 and 9: 3 Nope! The random value was 5 Enter a number between 0 and 9: hello The value is invalid invalid literal for int() with base 10: 'hello' Enter a number between 0 and 10: 4 Nope! The random value was 6
try...except
块带来了相当大的处理成本。因此,将try...except
块保持尽可能短是很重要的。因为我们知道错误发生在尝试将用户输入转换为整数的行上,所以我们将其包装在try...except
块中以捕获错误。
因此,try
/except
关键字用于防止程序执行中的任何异常行为,因为出现错误。它使得能够记录错误并采取补救措施。与try...except
块类似,还有try...except...else
和try...except...else
代码块。让我们通过几个例子快速回顾一下这些选项。
try…except…else
try...except...else
块在我们希望只有在没有引发异常时才执行特定代码块时特别有用。为了演示这个概念,让我们使用这个块来重写猜数字游戏示例:
try: input_value = int(value) except ValueError as error: print("The value is invalid %s" % error) else: if input_value < 0 or input_value > 9: print("Input invalid. Enter a number between 0 and 9.") elif input_value == rand_num: print("Your guess is correct! You win!") break else: print("Nope! The random value was %s" % rand_num)
使用try...except...else
块修改的猜数字游戏示例可与本章一起下载,文件名为try_except_else.py
。在这个例子中,程序仅在接收到有效的用户输入时才将用户输入与随机数进行比较。否则,它会跳过else
块并返回到循环顶部以接受下一个用户输入。因此,当try
块中的代码没有引发异常时,try...except...else
被用来执行特定的代码块。
try…except…else…finally
正如其名称所示,finally
块用于在离开try
块时执行一块代码。即使在引发异常后,这段代码也会被执行。这在我们需要在进入下一个阶段之前清理资源和释放内存时非常有用。
让我们使用我们的猜数字游戏来演示finally
块的功能。为了理解finally
关键字的工作原理,让我们使用一个名为count
的计数器变量,在finally
块中递增,以及另一个名为valid_count
的计数器变量,在else
块中递增。我们有以下代码:
count = 0 valid_count = 0 while True: # generate a random number between 0 and 9 rand_num = random.randrange(0,10) # prompt the user for a number value = input("Enter a number between 0 and 9: ") if value == 'x': print("Thanks for playing! Bye!") try: input_value = int(value) except ValueError as error: print("The value is invalid %s" % error) else: if input_value < 0 or input_value > 9: print("Input invalid. Enter a number between 0 and 9.") continue valid_count += 1 if input_value == rand_num: print("Your guess is correct! You win!") break else: print("Nope! The random value was %s" % rand_num) finally: count += 1 print("You won the game in %d attempts "\ "and %d inputs were valid" % (count, valid_count))
上述代码片段来自try_except_else_finally.py
代码示例(可与本章一起下载)。尝试执行代码示例并玩游戏。您将注意到赢得游戏所需的总尝试次数以及有效输入的数量:
Enter a number between 0 and 9: g The value is invalid invalid literal for int() with base 10: 'g' Enter a number between 0 and 9: 3 Your guess is correct! You win! You won the game in 9 attempts and 8 inputs were valid
这演示了try-except-else-finally
块的工作原理。当关键代码块(在try
关键字下)成功执行时,else
关键字下的任何代码都会被执行,而在退出try...except
块时(在退出代码块时清理资源时)finally
关键字下的代码块会被执行。
使用先前的代码示例玩游戏时提供无效的输入,以了解代码块流程。
连接到互联网 - 网络请求
现在我们已经讨论了try
/except
关键字,让我们利用它来构建一个连接到互联网的简单应用程序。我们将编写一个简单的应用程序,从互联网上获取当前时间。我们将使用 Python 的requests
库(requests.readthedocs.io/en/master/#
)。
requests
模块使得连接到网络和检索信息成为可能。为了做到这一点,我们需要使用requests
模块中的get()
方法来发出请求:
import requests response = requests.get('http://nist.time.gov/actualtime.cgi')
在上述代码片段中,我们将一个 URL 作为参数传递给get()
方法。在这种情况下,它是返回当前时间的 Unix 格式的 URL(en.wikipedia.org/wiki/Unix_time
)。
让我们利用try
/except
关键字来请求获取当前时间:
#!/usr/bin/python3 import requests if __name__ == "__main__": # Source for link: http://stackoverflow.com/a/30635751/822170 try: response = requests.get('http://nist.time.gov/actualtime.cgi') print(response.text) except requests.exceptions.ConnectionError as error: print("Something went wrong. Try again")
在前面的例子中(可以与本章一起下载,命名为internet_access.py
),请求是在try
块下进行的,响应(由response.text
返回)被打印到屏幕上。
如果在执行请求以检索当前时间时出现错误,将引发ConnectionError
(requests.readthedocs.io/en/master/user/quickstart/#errors-and-exceptions
)。这个错误可能是由于缺乏互联网连接或不正确的 URL 引起的。这个错误被except
块捕获。尝试运行这个例子,它应该返回time.gov
的当前时间:
<timestamp time="1474421525322329" delay="0"/>
requests 的应用-检索天气信息
让我们使用requests
模块来检索旧金山市的天气信息。我们将使用OpenWeatherMap API (openweathermap.org)来检索天气信息:
- 为了使用 API,注册一个 API 账户并获取一个 API 密钥(免费):
来自 openweathermap.org 的 API 密钥
- 根据 API 文档(openweathermap.org/current),可以使用
http://api.openweathermap.org/data/2.5/weather?zip=SanFrancisco&appid=API_KEY&units=imperial
作为 URL 来检索一个城市的天气信息。 - 用你的账户的密钥替换
API_KEY
,并在浏览器中使用它来检索当前的天气信息。你应该能够以以下格式检索到天气信息:
{"coord":{"lon":-122.42,"lat":37.77},"weather":[{"id":800, "main":"Clear","description":"clear sky","icon":"01n"}],"base": "stations","main":{"temp":71.82,"pressure":1011,"humidity":50, "temp_min":68,"temp_max":75.99},"wind": {"speed":13.04,"deg":291}, "clouds":{"all":0},"dt":1474505391,"sys":{"type":3,"id":9966, "message":0.0143,"country":"US","sunrise":1474552682, "sunset":1474596336},"id":5391959,"name":"San Francisco","cod":200}
天气信息(如前所示)以 JSON 格式返回。JavaScript 对象表示法(JSON)是一种广泛用于在网络上传递数据的数据格式。JSON 格式的主要优点是它是一种可读的格式,许多流行的编程语言支持将数据封装在 JSON 格式中。如前面的片段所示,JSON 格式使得以可读的名称/值对交换信息成为可能。
让我们回顾一下使用requests
模块检索天气并解析 JSON 数据:
- 用前面例子中的 URL(
internet_access.py
)替换为本例中讨论的 URL。这应该以 JSON 格式返回天气信息。 - requests 模块提供了一个解析 JSON 数据的方法。响应可以按以下方式解析:
response = requests.get(URL) json_data = response.json()
json()
函数解析来自 OpenWeatherMap API 的响应,并返回不同天气参数(json_data
)及其值的字典。- 由于我们知道 API 文档中的响应格式,可以从解析后的响应中检索当前温度:
print(json_data['main']['temp'])
- 把所有这些放在一起,我们有这个:
#!/usr/bin/python3 import requests # generate your own API key APP_ID = '5d6f02fd4472611a20f4ce602010ee0c' ZIP = 94103 URL = """http://api.openweathermap.org/data/2.5/weather?zip={} &appid={}&units=imperial""".format(ZIP, APP_ID) if __name__ == "__main__": # API Documentation: http://openweathermap.org/ current#current_JSON try: # encode data payload and post it response = requests.get(URL) json_data = response.json() print("Temperature is %s degrees Fahrenheit" % json_data['main']['temp']) except requests.exceptions.ConnectionError as error: print("The error is %s" % error)
前面的例子可以与本章一起下载,命名为weather_example.py
。该例子应该显示当前的温度如下:
Temperature is 68.79 degrees Fahrenheit
requests 的应用-将事件发布到互联网
在上一个例子中,我们从互联网上检索了信息。让我们考虑一个例子,在这个例子中,我们需要在互联网上发布传感器事件。这可能是你不在家时猫门打开,或者有人踩在你家门口的地垫上。因为我们在上一章中讨论了如何将传感器与树莓派 Zero 连接,所以让我们讨论一个场景,我们可以将这些事件发布到Slack——一个工作场所通讯工具,Twitter,或者云服务,比如Phant (data.sparkfun.com/
)。
在这个例子中,我们将使用requests
将这些事件发布到 Slack。每当发生传感器事件,比如猫门打开时,让我们在 Slack 上给自己发送直接消息。我们需要一个 URL 来将这些传感器事件发布到 Slack。让我们回顾一下生成 URL 以将传感器事件发布到 Slack:
- 生成 URL 的第一步是创建一个incoming webhook。Webhook 是一种可以将消息作为有效负载发布到应用程序(如 Slack)的请求类型。
- 如果您是名为TeamX的 Slack 团队成员,请在浏览器中启动您团队的应用程序目录,即
teamx.slack.com/apps
:
启动您团队的应用程序目录
- 在应用程序目录中搜索
incoming webhooks
,并选择第一个选项,Incoming WebHooks(如下截图所示):
选择 incoming webhooks
- 点击添加配置:
添加配置
- 当事件发生时,让我们向自己发送私人消息。选择 Privately to (you)作为选项,并通过单击添加 Incoming WebHooks 集成来创建一个 webhook:
选择 Privately to you
- 我们已经生成了一个 URL,用于发送有关传感器事件的直接消息(URL 部分隐藏):
生成的 URL
- 现在,我们可以使用先前提到的 URL 在 Slack 上向自己发送直接消息。传感器事件可以作为 JSON 有效负载发布到 Slack。让我们回顾一下如何将传感器事件发布到 Slack。
- 例如,让我们考虑在猫门打开时发布消息。第一步是为消息准备 JSON 有效负载。根据 Slack API 文档(
api.slack.com/custom-integrations)
),消息有效负载需要采用以下格式:
payload = {"text": "The cat door was just opened!"}
- 为了发布此事件,我们将使用
requests
模块中的post()
方法。在发布时,数据有效负载需要以 JSON 格式进行编码:
response = requests.post(URL, json.dumps(payload))
- 将所有内容放在一起,我们有:
#!/usr/bin/python3 import requests import json # generate your own URL URL = 'https://hooks.slack.com/services/' if __name__ == "__main__": payload = {"text": "The cat door was just opened!"} try: # encode data payload and post it response = requests.post(URL, json.dumps(payload)) print(response.text) except requests.exceptions.ConnectionError as error: print("The error is %s" % error)
- 在发布消息后,请求返回
ok
作为响应。这表明发布成功了。 - 生成您自己的 URL 并执行上述示例(与本章一起提供的
slack_post.py
一起下载)。您将在 Slack 上收到直接消息:
在 Slack 上直接发送消息
现在,尝试将传感器接口到 Raspberry Pi Zero(在前几章中讨论),并将传感器事件发布到 Slack。
还可以将传感器事件发布到 Twitter,并让您的 Raspberry Pi Zero 检查新邮件等。查看本书的网站以获取更多示例。
Flask web 框架
在我们的最后一节中,我们将讨论 Python 中的 Web 框架。我们将讨论 Flask 框架(flask.pocoo.org/
)。基于 Python 的框架使得可以使用 Raspberry Pi Zero 将传感器接口到网络。这使得可以在网络中的任何位置控制设备并从传感器中读取数据。让我们开始吧!
安装 Flask
第一步是安装 Flask 框架。可以按以下方式完成:
sudo pip3 install flask
构建我们的第一个示例
Flask 框架文档解释了构建第一个示例。根据文档修改示例如下:
#!/usr/bin/python3 from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!" if __name__ == "__main__": app.run('0.0.0.0')
启动此示例(与本章一起提供的flask_example.py
一起下载),它应该在 Raspberry Pi Zero 上启动一个对网络可见的服务器。在另一台计算机上,启动浏览器,并输入 Raspberry Pi Zero 的 IP 地址以及端口号5000
作为后缀(如下快照所示)。它应该将您带到服务器的索引页面,显示消息 Hello World!:
基于 Flask 框架的 Raspberry Pi Zero 上的 Web 服务器
您可以使用命令行终端上的ifconfig
命令找到 Raspberry Pi Zero 的 IP 地址。
Python 物联网入门指南(五)(3)https://developer.aliyun.com/article/1507235