Python 物联网入门指南(五)(2)

简介: Python 物联网入门指南(五)

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代表09之间的任意数字。这些文件可以按以下方式排序和列出:

# 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]表示文件名可以包含09之间的任意数字。由于我们正在寻找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代表09之间的任意数字。*代表任何文件扩展名。)

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 之间的数字:

  1. 使用 Python 的random模块生成一个随机数(在 0 到 9 之间)。如果用户猜测的数字正确,Python 程序会宣布用户为赢家并退出游戏。
  2. 如果用户输入是字母x,程序会退出游戏。
  3. 用户输入使用int()函数转换为整数。进行了一个合理性检查,以确定用户输入是否是 0 到 9 之间的数字。
  4. 整数与随机数进行比较。如果它们相同,程序会宣布用户为赢家并退出游戏。

让我们观察当我们故意向这个程序提供错误的输入时会发生什么(这里显示的代码片段可以在本章的下载中找到,文件名为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关键字:

  1. 从前面的例子中,我们知道当用户提供错误的输入时(例如,一个字母而不是 0 到 9 之间的数字),异常发生在第 10 行(用户输入转换为整数的地方),错误的性质被命名为ValueError
  2. 可以通过将其包装在try...except块中来避免程序执行的中断:
try: 
         input_value = int(value) 
      except ValueError as error:
         print("The value is invalid %s" % error)
  1. 在接收到用户输入时,程序会在try块下尝试将用户输入转换为整数。
  2. 如果发生了ValueErrorexcept块会捕获error,并将以下消息与实际错误消息一起打印到屏幕上:
except ValueError as error:
           print("The value is invalid %s" % error)
  1. 尝试执行代码示例并提供无效输入。您会注意到程序打印了错误消息(以及错误的性质),然后返回游戏循环的顶部并继续寻找有效的用户输入:
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...elsetry...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返回)被打印到屏幕上。

如果在执行请求以检索当前时间时出现错误,将引发ConnectionErrorrequests.readthedocs.io/en/master/user/quickstart/#errors-and-exceptions)。这个错误可能是由于缺乏互联网连接或不正确的 URL 引起的。这个错误被except块捕获。尝试运行这个例子,它应该返回time.gov的当前时间:

<timestamp time="1474421525322329" delay="0"/>

requests 的应用-检索天气信息

让我们使用requests模块来检索旧金山市的天气信息。我们将使用OpenWeatherMap API (openweathermap.org)来检索天气信息:

  1. 为了使用 API,注册一个 API 账户并获取一个 API 密钥(免费):

来自 openweathermap.org 的 API 密钥

  1. 根据 API 文档(openweathermap.org/current),可以使用http://api.openweathermap.org/data/2.5/weather?zip=SanFrancisco&appid=API_KEY&units=imperial作为 URL 来检索一个城市的天气信息。
  2. 用你的账户的密钥替换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 数据:

  1. 用前面例子中的 URL(internet_access.py)替换为本例中讨论的 URL。这应该以 JSON 格式返回天气信息。
  2. requests 模块提供了一个解析 JSON 数据的方法。响应可以按以下方式解析:
response = requests.get(URL) 
       json_data = response.json()
  1. json()函数解析来自 OpenWeatherMap API 的响应,并返回不同天气参数(json_data)及其值的字典。
  2. 由于我们知道 API 文档中的响应格式,可以从解析后的响应中检索当前温度:
print(json_data['main']['temp'])
  1. 把所有这些放在一起,我们有这个:
#!/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:

  1. 生成 URL 的第一步是创建一个incoming webhook。Webhook 是一种可以将消息作为有效负载发布到应用程序(如 Slack)的请求类型。
  2. 如果您是名为TeamX的 Slack 团队成员,请在浏览器中启动您团队的应用程序目录,即teamx.slack.com/apps

启动您团队的应用程序目录

  1. 在应用程序目录中搜索incoming webhooks,并选择第一个选项,Incoming WebHooks(如下截图所示):

选择 incoming webhooks

  1. 点击添加配置:

添加配置

  1. 当事件发生时,让我们向自己发送私人消息。选择 Privately to (you)作为选项,并通过单击添加 Incoming WebHooks 集成来创建一个 webhook:

选择 Privately to you

  1. 我们已经生成了一个 URL,用于发送有关传感器事件的直接消息(URL 部分隐藏):

生成的 URL

  1. 现在,我们可以使用先前提到的 URL 在 Slack 上向自己发送直接消息。传感器事件可以作为 JSON 有效负载发布到 Slack。让我们回顾一下如何将传感器事件发布到 Slack。
  2. 例如,让我们考虑在猫门打开时发布消息。第一步是为消息准备 JSON 有效负载。根据 Slack API 文档(api.slack.com/custom-integrations)),消息有效负载需要采用以下格式:
payload = {"text": "The cat door was just opened!"}
  1. 为了发布此事件,我们将使用requests模块中的post()方法。在发布时,数据有效负载需要以 JSON 格式进行编码:
response = requests.post(URL, json.dumps(payload))
  1. 将所有内容放在一起,我们有:
#!/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)
  1. 在发布消息后,请求返回ok作为响应。这表明发布成功了。
  2. 生成您自己的 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

相关实践学习
钉钉群中如何接收IoT温控器数据告警通知
本实验主要介绍如何将温控器设备以MQTT协议接入IoT物联网平台,通过云产品流转到函数计算FC,调用钉钉群机器人API,实时推送温湿度消息到钉钉群。
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
相关文章
|
2天前
|
数据采集 运维 API
适合所有编程初学者,豆瓣评分8.6的Python入门手册开放下载!
Python是一种跨平台的计算机程序设计语言,它可以用来完成Web开发、数据科学、网络爬虫、自动化运维、嵌入式应用开发、游戏开发和桌面应用开发。 Python上手很容易,基本有其他语言编程经验的人可以在1周内学会Python最基本的内容(PS:没有基础的人也可以直接学习,速度会慢一点) 今天给小伙伴们分享一份Python语言及其应用的手册,这份手册主要介绍 Python 语言的基础知识及其在各个领域的具体应用,基于最新版本 3.x。
|
5天前
|
数据可视化 API Python
Python零基础“圣经”!300W小白从入门到精通首选!
今天分享的这本书在让你尽快学会 Python基础知识的同时,能够编写并正确的运行程序(游戏、数据可视化、Web应用程序) 最大的特色在于,在为初学者构建完整的 Python 语言知识体系的同时,面向实际应用情境编写代码样例,而且许多样例还是 后续实践项目部分的伏笔。实践项目部分的选题经过精心设计,生动详尽 又面面俱到。相信这本书能够得到更多 Python 初学者的喜爱。
|
6天前
|
Python
小白入门必备!计科教授的Python精要参考PDF开放下载!
随着互联网产业的高速发展,在网络上早已积累了极其丰富的Python学习资料,任何人都可以基于这些资源,自学掌握 Python。 但实际上,网络上充斥的资源太多、太杂且不成体系,在没有足够的编程/工程经验之前,仅靠“看”线上资源自学,的确是一件非常困难的事。
|
6天前
|
数据可视化 API Python
豆瓣评分9.4!堪称经典的Python入门圣经,你还没看过吗?
最理想的新人入门书应该满足两个特点:第一就是内容通俗易懂;第二就是要有实战,能够让读者在学完之后知道具体怎么用。 今天给小伙伴们分享的这份Python入门手册,在为初学者构建完整的Python语言知识体系的同时,面向实际应用情境编写代码样例,而且许多样例还是后续实践项目部分的伏笔。实践项目部分的选题经过精心设计,生动详尽又面面俱到。
|
8天前
|
数据采集 运维 API
适合所有编程初学者,豆瓣评分8.6的Python入门手册开放下载!
Python是一种跨平台的计算机程序设计语言,它可以用来完成Web开发、数据科学、网络爬虫、自动化运维、嵌入式应用开发、游戏开发和桌面应用开发。 Python上手很容易,基本有其他语言编程经验的人可以在1周内学会Python最基本的内容(PS:没有基础的人也可以直接学习,速度会慢一点)
|
9天前
|
数据采集 SQL 数据可视化
使用Python和Pandas库进行数据分析的入门指南
使用Python和Pandas库进行数据分析的入门指南
72 0
|
9天前
|
Linux iOS开发 MacOS
Python入门指南
Python入门指南
32 0
|
10天前
|
数据采集 前端开发 JavaScript
Python爬虫入门
网络爬虫是自动抓取网页数据的程序,通过URL获取网页源代码并用正则表达式提取所需信息。反爬机制是网站为防止爬取数据设置的障碍,而反反爬是对这些机制的对策。`robots.txt`文件规定了网站可爬取的数据。基础爬虫示例使用Python的`urllib.request`模块。HTTP协议涉及请求和响应,包括状态码、头部和主体。`Requests`模块是Python中常用的HTTP库,能方便地进行GET和POST请求。POST请求常用于隐式提交表单数据,适用于需要发送复杂数据的情况。
16 1
|
13天前
|
机器学习/深度学习 人工智能 数据可视化
Python编程入门:从零开始探索编程的奇妙世界
这篇教程引导初学者入门Python编程,从安装Python开始,逐步讲解基本语法,如`print()`、变量、条件判断、循环以及自定义函数。文章强调了Python在数据处理、数据分析、人工智能和机器学习等领域的重要性,并鼓励学习者探索Python的广泛应用,开启编程之旅。
|
14天前
|
数据可视化 API Python
Python零基础“圣经”!300W小白从入门到精通首选!
今天分享的这本书在让你尽快学会 Python基础知识的同时,能够编写并正确的运行程序(游戏、数据可视化、Web应用程序) 最大的特色在于,在为初学者构建完整的 Python 语言知识体系的同时,面向实际应用情境编写代码样例,而且许多样例还是 后续实践项目部分的伏笔。实践项目部分的选题经过精心设计,生动详尽 又面面俱到。相信这本书能够得到更多 Python 初学者的喜爱。