乐趣区

Python教程05模块与API

大纲

  • 环境
  • 包管理
  • 模块
  • 时间
  • API
  • 练习

环境

Python 环境 :我们回到第一次课上没有说到的venv 这个文件夹。

这个文件夹其实就是这个项目所使用的 Python 环境目录。项目实际执行的 python 在 venv 目录下。
为什么不是我们安装 Python 时的目录
Pycharm 在默认创建项目时会根据我们安装的 Python 创建一个 虚拟环境 在项目下。
这个虚拟环境是这个 项目专用 的,是 干净 的,可以 不受 其他项目的 影响
干净 要表达的是 最原始 的 Python 环境。
互不影响 的作用体现在多个项目对环境的 依赖 不同,甚至可能 冲突

我们也可以选择安装的原始环境进行开发。

包管理

Package】就是环境依赖中最主要的内容。
包其实就是一个 程序目录 ,在这个目录下包含了 许多模块 ,方便我们调用。
如上次课就使用到了一个 re 模块就是 Python 自带包里的一个模块。
Python自带包 ,在安装了 Python 后就可以直接使用。
除了自带包,我们还要使用到 第三方包
大量的第三方包是支撑 Python 开发的重要一环。现在几乎所有的开发领域都可以使用 Python。

Pycharm 中的包管理 :进入配置 File => Settings

选择Project code > Project Interpreter 进入包管理

包管理界面

已安装的包显示了 包的名称 当前版本 【Version】,以及 最新的版本 【Lastest version】。
默认 情况下会有 pipsetuptools两个包,这两个是 Python 用来 管理包的包,必须存在。

添加包 :点击加号【+

我们输入 requests【一个用于请求的包】。
选择正确的包后,点击 Install Package
进行安装

安装成功


我们就看到了 requests 包,这时你会发现还多了很多的包。
这些包时 requests 包里需要调用的包【依赖包】,要使用 requests 也必须安装这些包。

国内源 :在安装时,你可能会觉得速度很慢,这时我们就要使用国内源。
国内源就是设在国内的服务器,访问速度比默认的要快。【默认服务器在国外】
在安装包页面,点击 Manage Repositories

默认的地址就是 https://pypi.python.org/simple
我们点击加号【+】,添加源。

添加源 :输入地址,我选择了阿里的源。

再次搜索包就会出现两个,选择阿里源下载就比较快。

几个常用的国内源
清华:https://pypi.tuna.tsinghua.ed…
阿里云:https://mirrors.aliyun.com/py…
中国科技大学 https://pypi.mirrors.ustc.edu…
豆瓣:https://pypi.douban.com/simple

模块

模块 就是一个 Python 文件。文件中包含 方法和类 ,或者其他内容。
我们之前所写的程序都是在一个文件中实现,其实这也是一个模块。
为了实现 代码复用,我们会将方法和类放到模块中去,并由另一个执行文件来调用。

创建一个模块 :我们编写一个utils 工具模块。
创建 utils.py 文件,写入两个方法。与之前没有任何的不同。

def warning(content):
    print('【warning】{}'.format(content))
def error(content):
    print('【error】{}'.format(content))

模块调用importfrom

import utils
utils.warning('s')
utils.error('ss')

import后跟上 模块名 ,就完成了模块的导入。
然后我们就可以 通过模块名调用 到该方法。
另一种方式是from 导入,特点是导入后不需要用模块名调用,直接使用方法或类。
from … import 表示从某个模块中导入方法或类。

from utils import *
warning('s')
error('ss')

星号【*】代表导入 所有 的方法或类。

from utils import warning
warning('ss')

或者 直接指定 要导入的方法或类,多个用 逗号隔开

from utils import warning, error

创建包 :通过创建包,将模块集合起来管理。
右键 => New => Python Package

我们创建一个 api 模块。

创建好的包显示为

包下面默认有个 __init__.py 文件,是 Python 用来 标识 该目录为包的。
我们在 api 包下创建几个模块,来编写我们下面要学习的 API 请求功能。

时间

在编写 API 之前,我们先学习使用一个常用的 内置模块 【时间】:datetime
时间模块 是用来处理时间的 Python 自带的包。我们可以方便的对时间进行操作。

导入包:从 datetime 包中导入 datetime 模块

from datetime import datetime

时间模块在导入上一般使用 from 的模式,这样在调用时比较简单。
由于在时间处理上一般都用该包,所以一般也不会有同名模块造成的冲突。

获取当前时间 :使用 datetime 模块下的now 方法获得当前时间。

now = datetime.now()
print('现在时间是' + str(now))

输出

时间信息 :我们获得了时间,但是打印时并不是我们想要的格式。
通过获取时间的年、月、日、时、分、秒、毫秒等信息,来组合我们要的时间。

year = now.year                 # 年
month = now.month               # 月
day = now.day                   # 日
hour = now.hour                 # 时
minute = now.minute             # 分
second = now.second             # 秒
microsecond = now.microsecond   # 毫秒
t = int(now.timestamp())        # 时间戳

时间戳 是一个 10 位的数字,代表了从 1970 年 1 月 1 日 0 点开始所经历的秒数,是开发过程中常用的计量方式。
自定义格式:

print(str(year) + '-' + str(month) + '-' + str(day))
print('{}-{}-{}'.format(year, month, day))

时间格式化 strftime。时间的格式化与字符串不同,使用 百分号 %起头的 标准替换符

import locale
locale.setlocale(locale.LC_CTYPE, 'chinese')    # 解决中文问题
print(now.strftime('%Y 年 %m 月 %d 日 第 %W 周 星期 %w'))

时间创建 :一种方式我们可以通过 反格式化strptime】来进行。

date = datetime.strptime('2019 年 3 月 16 日', '%Y 年 %m 月 %d 日')
print(date)

datetimestrptime 方法第一个参数是 要转换的时间 ,第二个参数是 时间格式

try:
    birthday = input('输入你的生日(例:2019-03-16)?')
    birthday = datetime.strptime(birthday, '%Y-%m-%d')
    print(birthday)
except Exception as e:
    print('时间格式输入错误')

对象创建 :对象创建是另一种时间创建方式,是 面向对象 的编程方式。面向对象的内容,下次课会详细介绍。
datetime其实是一个 ,可以通过直接创建来生成。

birthday = datetime(year=2019, month=3, day=16)

如上的代码,直接调用 datetime 类,就可以创建出 时间对象
通过 control 键,我们可以进入其所调用的具体方法内容。

__init__就是调用的类 构造方法 self 暂时不管,后面的参数就是该方法的参数。
我们就可以创建任意时间了。

时间计算 timedelta
除了 datetime 模块,我们还需要引入 timedetla 模块。

from datetime import datetime, timedelta

计算使用加减号进行。

yesterday = now - timedelta(days=1)     # 昨天,减去一天
delta = now - yesterday                 # 时间
print(delta.days)                       # 相差几天

timedelta的参数还有 weekssecondsminuteshours 等。

API

API 请求是开发过程常用的一个功能。我们使用刚刚安装的 requests 包来完成。

实例 :时间模块中,我们只能知道某一天是周几来判断是不是放假。
实际中我们还需要知道某天是不是放假的需求。这时我们就需要 API 的帮助了。
我们选择了 聚合数据 【https://www.juhe.cn/】这个第三方平台的免费 API 进行讲解。
万年历 【https://www.juhe.cn/docs/api/…】就是我们要使用的 API。
注册、认证、申请该 API 成功后。

我们可以在【测试 】中进行该接口的调试,或者使用Postman 进行。

调试完成后我们就可以开始写代码了。

模块编写
先导入需要的包,并定义两个变量 聚合平台的 URL 地址 申请到的 appkey

from datetime import datetime   # 时间包
import requests                 # 请求包
appkey = 'xxxxxxxxxxxxxxxxx'    # 申请到的 appkey
juhe_url = 'http://v.juhe.cn/’# 聚合数据的网址

requests 的基本使用

respone = requests.get(url=url, headers=headers, params=params) # get 请求
respone = requests.post(url=url, headers=headers, data=params)  # post 请求

paramsdata 都是 字典 类型,表示两种请求中的 参数 headers 也是 字典 ,表示 http 请求头

编写方法

def calendar_day(date=datetime.now()):
    url = juhe_url + 'calendar/day'
    params = {'date': date.strftime('%Y-%m-%d'),
        'key':  appkey
    }
    response = requests.get(url=url, params=params)
    if response.status_code == 200:     # 请求成功
        return response.content         # 返回结果
    else:
        return None                     # 请求失败

在请求完成后,response.status_code是请求返回的状态码,200表示请求正常。response.content是返回内容。

当状态码不是 200 时,返回空值 None 表示 请求失败
返回的内容是 JSON 形式,我们暂时还无法直接使用。

JSON:该接口返回内容就是json

{
    "reason":"Success",
    "result":{
        "data":{
            "holiday":"元旦",
            "avoid":"伐木. 纳畜. 破",
            "animalsYear":"兔",
            "desc":"2012 年 1 月 1 日",
            "weekday":"星期日",
            "suit":"祭祀. 开光. 理发",
            "lunarYear":"辛卯年",
            "lunar":"腊月初八",
            "year-month":"2012-1",
            "date":"2012-1-1"
        }
    },
    "error_code":0
}

Json 是一种 数据格式 ,用于 数据的传输
其与 Python 的字典列表组合的结构是一样的。
所以我们可以将 jsonpython格式 互相转换

import json
# json 格式转换为 python 格式
data = json.loads(content)
print(data)
# python 格式转换为 json 格式
content2 = json.dumps(data)
print(content2)

解析 JSON

return json.loads(response.content)

或者使用封装好的方法 response.json 也很方便。

return response.json()

调用该模块:编写了一个 is_holiday 方法来判断

from api import juhe            # 从 api 包导入 juhe 模块
from datetime import datetime
def is_holiday(date=datetime.now()):
    info = juhe.calendar_day(date)      # 获得数据
    if info is not None and info['reason'] == 'Success':    # 验证数据正确
        result = info['result']
        if 'holiday' in result:
            return True         # 有 holiday 时,表示时假日
        else:
            return False
    return None

练习

1、选择一个 API 进行请求模块的练习。
2、对于 is_holiday 这个方法,我们免费的请求次数只有每天 100 次,
假设我们的用户可能有很多,每天的请求量远不止 100 次。
我们现在只需要今天的数据,如何可以使我们不付费?

退出移动版