手把手教你使用Python打造一款摸鱼倒计界面

大家好,我是吴老板。

前言

前段时间在微博看到一段摸鱼人的倒计时模板,感觉还挺有趣的。


于是我用了一小时的时间写了个页面出来 摸鱼办地址 (当然是摸鱼的时间啦)。

模板是这样的:

摸鱼办公室

【摸鱼办公室】今天是 2021-11-30 星期二

你好,摸鱼人,工作再累,一定不要忘记摸鱼哦 ! 有事没事起身去茶水间去廊道去天台走走,别老在工位上坐着。多喝点水,钱是老板的,但命是自己的 !

距离 周末 放假还有 2 天

距离 元旦 放假还有 3 天

距离 过年 放假还有 34 天

距离 清明节 放假还有 97 天

距离 劳动节 放假还有 123 天

距离 端午节 放假还有 156 天

距离 中秋节 放假还有 255 天

距离 国庆节 放假还有 276 天


  • 由于前端是单页面服务,直接撸一个原始的 html 网页就行。
  • FastAPI 对于异步请求是一把好手、更轻、性能更佳。
  • 挂上一层 Nginx 让它看起来像那么回事儿。

实现过程

  • 首先要知道、除了静态文字之外的比如当前日期、距离节日放假的天数等都是动态返回的,我需要使用 Jinja2 模板进行动态绑定。
  • 我应该把重点放在时间的处理上。
  • 而且在这个模板中,有阳历的节日,也是阴历的节日,我需要转换。

初始化一个 FastAPI 对象并声明静态页面的模板目录 (Jinja2Templates)

# -*- coding: utf-8 -*-
import datetime
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from zhdate import ZhDate as lunar_date

app = FastAPI(
    debug=False,
    title="My API",
    docs_url="/docs",
    openapi_url=f"/openapi.json"
)

templates = Jinja2Templates(directory="templates")

可以看到的是我用到了 zhdate 这个库、主要用于阴历和阳历之间的相互转换。用法如下

today = datetime.date.today()
print(today.year, today.month, today.day)
print("大年时间: ", lunar_date(today.year+1, 1, 1).to_datetime().date())
print("端午时间: ", lunar_date(today.year, 5, 5).to_datetime().date())
print("中秋时间: ", lunar_date(today.year, 8, 15).to_datetime().date())
print("元旦时间: ", f"{today.year+1}-01-01")
print("清明时间: ", f"{today.year}-04-05")
print("劳动时间: ", f"{today.year}-05-01")
print("国庆时间: ", f"{today.year}-10-01")

我们可以梳理一下:

  • 计算距离 大年、元旦 的天数时,要在年份上 +1
  • 计算距离 其他节日 的天数时,要判断天数差是否小于 0,如果是,则年份需要 +1,因为已经过去的节日对此没有意义
distance_big_year = (lunar_date(today.year + 1, 1, 1).to_datetime().date() - today).days

distance_5_5 = (lunar_date(today.year, 5, 5).to_datetime().date() - today).days
distance_5_5 = distance_5_5 if distance_5_5 > 0 else (
        lunar_date(today.year + 1, 5, 5).to_datetime().date() - today).days

distance_8_15 = (lunar_date(today.year, 8, 15).to_datetime().date() - today).days
distance_8_15 = distance_8_15 if distance_8_15 > 0 else (
        lunar_date(today.year + 1, 8, 15).to_datetime().date() - today).days

distance_year = (datetime.datetime.strptime(f"{today.year + 1}-01-01", "%Y-%m-%d").date() - today).days

distance_4_5 = (datetime.datetime.strptime(f"{today.year}-04-05", "%Y-%m-%d").date() - today).days
distance_4_5 = distance_4_5 if distance_4_5 > 0 else (
        datetime.datetime.strptime(f"{today.year + 1}-04-05", "%Y-%m-%d").date() - today).days

distance_5_1 = (datetime.datetime.strptime(f"{today.year}-05-01", "%Y-%m-%d").date() - today).days
distance_5_1 = distance_5_1 if distance_5_1 > 0 else (
        datetime.datetime.strptime(f"{today.year + 1}-05-01", "%Y-%m-%d").date() - today).days

distance_10_1 = (datetime.datetime.strptime(f"{today.year}-10-01", "%Y-%m-%d").date() - today).days
distance_10_1 = distance_10_1 if distance_10_1 > 0 else (
        datetime.datetime.strptime(f"{today.year + 1}-10-01", "%Y-%m-%d").date() - today).days

怎么样? 我的命名足够疯狂吧。

接下来需要计算一下距离周末的天数。

def get_week_day(date):
    week_day_dict = {
        0: '星期一',
        1: '星期二',
        2: '星期三',
        3: '星期四',
        4: '星期五',
        5: '星期六',
        6: '星期天',
    }
    day = date.weekday()
    return week_day_dict[day]

week_day_ = get_week_day(today)
print(f"今天是: {week_day_}") # 先获取今天是星期几

按照每周 5 个工作日计算,今天距离周末的天数就是

5 - today.weekday() # today.weekday() 今天距离周末

现在将所有的数据组装起来

time_ = [
    {"v_": distance_year, "title": "元旦"},  # 距离元旦
    {"v_": distance_big_year, "title": "过年"},  # 距离过年
    {"v_": distance_4_5, "title": "清明节"},  # 距离清明
    {"v_": distance_5_1, "title": "劳动节"},  # 距离劳动
    {"v_": distance_5_5, "title": "端午节"},  # 距离端午
    {"v_": distance_8_15, "title": "中秋节"},  # 距离中秋
    {"v_": distance_10_1, "title": "国庆节"},  # 距离国庆
]

至于为什么是 List 而不是 Dict,那是我需要做一个根据距离天数的排序,让最先放假的节日放于最前面, 这样看起来会舒服得多。

time_ = sorted(time_, key=lambda x: x['v_'], reverse=False)

接下来要写一个 路由,将数据传入到 html 页面中去。

@app.get("/", response_class=HTMLResponse)
async def readme(request: Request):
    return templates.TemplateResponse("readme.html",
                                      {"request": request, "time_": time_, "now_": now_, "week_day_": week_day_})

来看一下完整的代码 (main.py):

# -*- coding: utf-8 -*-
import datetime
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from zhdate import ZhDate as lunar_date

app = FastAPI(
    debug=False,
    title="My API",
    docs_url=f"/docs",
    openapi_url=f"/openapi.json"
)

templates = Jinja2Templates(directory="templates")

today = datetime.date.today()

# print(today.year, today.month, today.day)
# print("大年时间: ", lunar_date(today.year+1, 1, 1).to_datetime().date())
# print("端午时间: ", lunar_date(today.year, 5, 5).to_datetime().date())
# print("中秋时间: ", lunar_date(today.year, 8, 15).to_datetime().date())
# print("元旦时间: ", f"{today.year+1}-01-01")
# print("清明时间: ", f"{today.year+1}-04-05")
# print("劳动时间: ", f"{today.year+1}-05-01")
# print("国庆时间: ", f"{today.year+1}-10-01")

distance_big_year = (lunar_date(today.year + 1, 1, 1).to_datetime().date() - today).days

distance_5_5 = (lunar_date(today.year, 5, 5).to_datetime().date() - today).days
distance_5_5 = distance_5_5 if distance_5_5 > 0 else (
        lunar_date(today.year + 1, 5, 5).to_datetime().date() - today).days

distance_8_15 = (lunar_date(today.year, 8, 15).to_datetime().date() - today).days
distance_8_15 = distance_8_15 if distance_8_15 > 0 else (
        lunar_date(today.year + 1, 8, 15).to_datetime().date() - today).days

distance_year = (datetime.datetime.strptime(f"{today.year + 1}-01-01", "%Y-%m-%d").date() - today).days

distance_4_5 = (datetime.datetime.strptime(f"{today.year}-04-05", "%Y-%m-%d").date() - today).days
distance_4_5 = distance_4_5 if distance_4_5 > 0 else (
        datetime.datetime.strptime(f"{today.year + 1}-04-05", "%Y-%m-%d").date() - today).days

distance_5_1 = (datetime.datetime.strptime(f"{today.year}-05-01", "%Y-%m-%d").date() - today).days
distance_5_1 = distance_5_1 if distance_5_1 > 0 else (
        datetime.datetime.strptime(f"{today.year + 1}-05-01", "%Y-%m-%d").date() - today).days

distance_10_1 = (datetime.datetime.strptime(f"{today.year}-10-01", "%Y-%m-%d").date() - today).days
distance_10_1 = distance_10_1 if distance_10_1 > 0 else (
        datetime.datetime.strptime(f"{today.year + 1}-10-01", "%Y-%m-%d").date() - today).days


def get_week_day(date):
    week_day_dict = {
        0: '星期一',
        1: '星期二',
        2: '星期三',
        3: '星期四',
        4: '星期五',
        5: '星期六',
        6: '星期天',
    }
    day = date.weekday()
    return week_day_dict[day]


# print("距离大年: ", distance_big_year)
# print("距离端午: ", distance_5_5)
# print("距离中秋: ", distance_8_15)
# print("距离元旦: ", distance_year)
# print("距离清明: ", distance_4_5)
# print("距离劳动: ", distance_5_1)
# print("距离国庆: ", distance_10_1)
# print("距离周末: ", 5 - today.weekday())

now_ = f"{today.year}{today.month}{today.day}日"
week_day_ = get_week_day(today)
time_ = [
    {"v_": 5 - 1 - today.weekday(), "title": "周末"},  # 距离周末
    {"v_": distance_year, "title": "元旦"},  # 距离元旦
    {"v_": distance_big_year, "title": "过年"},  # 距离过年
    {"v_": distance_4_5, "title": "清明节"},  # 距离清明
    {"v_": distance_5_1, "title": "劳动节"},  # 距离劳动
    {"v_": distance_5_5, "title": "端午节"},  # 距离端午
    {"v_": distance_8_15, "title": "中秋节"},  # 距离中秋
    {"v_": distance_10_1, "title": "国庆节"},  # 距离国庆
]

time_ = sorted(time_, key=lambda x: x['v_'], reverse=False)


@app.get("/", response_class=HTMLResponse)
async def readme(request: Request):
    return templates.TemplateResponse("readme.html",
                                      {"request": request, "time_": time_, "now_": now_, "week_day_": week_day_})


if __name__ == '__main__':
    import uvicorn

    uvicorn.run(app='main:app', host="0.0.0.0", port=8080, reload=True)

最后就到了 html 页面部分了,来看一下主要的传值。

<center>
    【摸鱼办公室】今天是 {{ now_ }} {{ week_day_ }}
    <br><br>
    {% for v_ in time_ %}
        <p> 距离 {{ v_.title }} 放假还有 {{ v_.v_ }} 天</p>
    {% else %}
        <p>沒有任何值</p>
    {% endfor %}

</center>

这样整个的路由构造和页面编写就算是完成了。

最后通过 Nginx 部署到我的站点上。

摸鱼办预览地址

代码已经上传至 摸鱼办

https://github.com/PY-GZKY/moyu

你可能会有更多的想法、可以在评论区讨论、一切为了摸鱼。

小伙伴们,快快用实践一下吧!如果在学习过程中,有遇到任何问题,欢迎加我好友,我拉你进Python学习交流群共同探讨学习。

盘点3种Python网络爬虫过程中的中文乱码的处理方法

大家好,我是Python进阶者。前几天给大家分享了一些乱码问题的文章,感兴趣的小伙伴可以前往:UnicodeEncodeError: ‘gbk’ codec can’t encode character解决方法,这里再次给大家祭出网络爬虫过程中三种中文乱码的处理方案,希望对大家的学习有所帮助。

前言

前几天有个粉丝在Python交流群里问了一道关于使用Python网络爬虫过程中中文乱码的问题,如下图所示。

看上去确实头大,对于爬虫初学者来说,这个乱码摆在自己面前,犹如拦路虎一般难顶。不过别慌,小编在这里给大家整理了三种方法,专门用于针对中文乱码的,希望大家在后面再次遇到中文乱码的问题,在此处可以得到灵感!

一、思路

其实解决问题的关键点就是在于一点,就是将乱码的部分进行处理,而处理的方案主要可以从两个方面进行出发。其一是针对整体网页进行提前编码,其二是针对局部具体中文乱码的部分进行编码处理。这里例举3种方法,肯定还有其他的方法的,也欢迎大家在评论区谏言。

二、分析

其实关于中文乱码的表现形式有很多,但是常见的两种如下:

1、当出现网页编码为gbk,获取到的内容在控制台打印类似如下情况的时候:

ÃÀÅ® µçÄÔ×À ¼üÅÌ »ú·¿ ¿É°® С½ã½ã4k±ÚÖ½

2、当出现网页编码为gbk,获取到的内容在控制台打印类似如下情况的时候:

�װŮ�� ��Ů ˮ СϪ Ψ��

虽然看上去控制台输出正常,没有报错:

Process finished with exit code 0

但是输出的中文内容,却不是普通人能看得懂的。

这种情况下的话,就可以通过使用本文给出的三种方法进行解决,屡试不爽!

三、具体实现

1)方法一:将requests.get().text改为requests.get().content

我们可以看到通过text()方法获取到的源码,之后进行打印输出的话,确实是会存在乱码的,如下图所示。

此时可以考虑将请求变为.content,得到的内容就是正常的了。

2)方法二:手动指定网页编码

# 手动设定响应数据的编码格式
response.encoding = response.apparent_encoding

这个方法稍微复杂一些,但是比较好理解,对于初学者来说,还是比较好接受的。

如果觉得上面的方法很难记住,或者你可以尝试直接指定gbk编码也可以进行处理,如下图所示:

上面介绍的两种方法都是针对网页进行整体编码,效果显著,接下来的第三种方法就是针对中文局部乱码部分使用通用编码方法进行处理。

3)方法三:使用通用的编码方法

img_name.encode('iso-8859-1').decode('gbk')

使用通用的编码方法,对中文出现乱码的地方进行编码设定即可。还是当前的这个例子,针对img_name进行编码设定,指定编码并进行解码,如下图所示。

如此一来,中文乱码的问题就迎刃而解了。

四、总结

我是Python进阶者。本文基于粉丝提问,针对Python网络爬虫过程中的中文乱码问题,给出了3种乱码解决方法,顺利帮助粉丝解决了问题。虽然文中例举了3种方法,但是小编相信肯定还有其他的方法的,也欢迎大家在评论区谏言。

小伙伴们,快快用实践一下吧!如果在学习过程中,有遇到任何问题,欢迎加我好友,我拉你进Python学习交流群共同探讨学习

手把手教你使用Python网络爬虫获取B站视频选集内容(附源码)

大家好,我是Python进阶者。
前言
前几天雪球兄在Python交流群里分享了一个获取B站视频选集的Python代码,小编觉得非常奈斯,这里整理成一篇小文章,分享给大家学习。
关于雪球兄,大家应该都熟悉了,之前他写过Python实战文章,好评如潮,没来得及看的小伙伴,可以戳这里了:

盘点常用验证码标注和识别项目线上部署三种方式——VUE前端、Java后端和Python后端部署

Python项目实战篇——常用验证码标注&识别(CNN神经网络模型训练/测试/部署)

Python项目实战篇——常用验证码标注&识别(前端+后端实现高效率数据标注)

Python项目实战篇——常用验证码标注&识别(数据采集/预处理/字符图切割)

Python项目实战篇——常用验证码标注和识别(需求分析和实现思路)

之前也有给大家分享B站的一些文章,感兴趣的话可以看看这个文章,Python网络爬虫+数据分析:手把手教你用Python网络爬虫获取B站UP主10万条数据并用Pandas库进行趣味数据分析。

一、背景引入
一提到B站,第一印象就是视频,相信很多小伙伴和我一样,都想着去利用网络爬虫技术获取B站的视频吧,但是B站视频其实没有那么好拿到的,关于B站的视频获取,之前有介绍通过you-get库进行实现,感兴趣的小伙伴可以看这篇文章:You-Get 就是这么强势!。

言归正传,经常在B站上学习的小伙伴们可能经常会遇到有的博主连载几十个,甚至几百个视频,尤其像这种编程语言、课程、工具使用等连续的教程,就会出现选集系列,如下图所示。

当然这些选集的字段我们肉眼也是可以看得到的。只是通过程序来实现的话,可能真没有想象的那么简单。那么这篇文章的目标呢,就是通过Python网络爬虫技术,基于selenium库,实现视频选集的获取。

二、具体实现
这篇文章我们用的库是selenium,这个是一个用于模拟用户登录的库,虽然给人的感觉是慢,但是在网络爬虫领域,这个库还是用的蛮多的,用它来模拟登录、获取数据屡试不爽。下面是实现视频选集采集的所有代码,欢迎大家亲自动手实践。

# coding: utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

class Item:
page_num = “”
part = “”
duration = “”

def __init__(self, page_num, part, duration):
self.page_num = page_num
self.part = part
self.duration = duration

def get_second(self):
str_list = self.duration.split(“:”)
sum = 0
for i, item in enumerate(str_list):
sum += pow(60, len(str_list) – i – 1) * int(item)

return sum

def get_bilili_page_items(url):
options = webdriver.ChromeOptions()
options.add_argument(‘–headless’) # 设置无界面
options.add_experimental_option(‘excludeSwitches’, [‘enable-automation’])
# options.add_experimental_option(“prefs”, {“profile.managed_default_content_settings.images”: 2,
# “profile.managed_default_content_settings.flash”: 0})

browser = webdriver.Chrome(options=options)
# browser = webdriver.PhantomJS()
print(“正在打开网页…”)
browser.get(url)

print(“等待网页响应…”)
# 需要等一下,直到页面加载完成
wait = WebDriverWait(browser, 10)
wait.until(EC.visibility_of_element_located((By.XPATH, ‘//*[@class=”list-box”]/li/a’)))

print(“正在获取网页数据…”)
list = browser.find_elements_by_xpath(‘//*[@class=”list-box”]/li’)
# print(list)
itemList = []

second_sum = 0

# 2.循环遍历出每一条搜索结果的标题
for t in list:
# print(“t text:”,t.text)
element = t.find_element_by_tag_name(‘a’)
# print(“a text:”,element.text)
arr = element.text.split(‘\n’)
print(” “.join(arr))
item = Item(arr[0], arr[1], arr[2])
second_sum += item.get_second()
itemList.append(item)

print(“总数量:”, len(itemList))
# browser.page_source

print(“总时长/分钟:”, round(second_sum / 60, 2))
print(“总时长/小时:”, round(second_sum / 3600.0, 2))

browser.close()

return itemList

get_bilili_page_items(“https://www.bilibili.com/video/BV1Eb411u7Fw”)
这里用到的选择器是xpath,利用视频示例是B站的《高等数学》同济版 全程教学视频(宋浩老师)视频选集,大家如果想抓取其他视频选集的话,只需要更改上述代码的最后一行的URL链接即可。

三、常见问题
在运行过程中小伙伴们应该会经常遇到这个问题,如下图所示。

这个是因为谷歌驱动版本问题导致的,只需要根据提示,去下载对应的驱动版本即可,驱动下载链接:

https://chromedriver.storage.googleapis.com/index.html

四、总结
我是Python进阶者。这篇文章主要给大家介绍了B站视频选集内容的获取方法,基于网络爬虫,通过selenium库和xpath选择器进行实现,并且给大家例举了常见问题的处理方法。小伙伴们,快快用实践一下吧!如果在学习过程中,有遇到任何问题,欢迎加我好友,我拉你进Python学习交流群共同探讨学习。

Mysql查询语句之连表查询和增删改查语句补充

前言

Hey,大家好,我是码农星期八!

上次怎么大概说了一下or,!=,in/not in between,like,limit,order by,group by。

但是还没完,咱们接着往下说!

查询

我们的数据是这样的。

Mysql查询语句之连表查询和增删改查语句补充

发现class_id是一个数字,这是因为我们在设计时,将学生表班级表分开设计的。

Mysql查询语句之连表查询和增删改查语句补充

但是如果我们偏偏想要查询这个人是几班的,怎么办?

连表查询

方式一,where连表

语法

SELECT * from1,表2 WHERE1.外键列=表2.被外键列;
SELECT1.1,表1.2,表2.1,... from1,表2 WHERE1.外键列=表2.被外键列;

连表显示所有列

SELECT * from student,class WHERE student.class_id=class.id;

执行结果

Mysql查询语句之连表查询和增删改查语句补充

喏,这样就知道哪个学生是哪个班的了!

连表显示指定列

SELECT student.id,student.`name`,class.title from student,class WHERE student.class_id=class.id;

执行结果

Mysql查询语句之连表查询和增删改查语句补充

方式二,left连表

通过where连表固然简单,但是缺点明显。

因为我们的where后面是要跟判断条件的,使用where进行连表会造成逻辑有些混乱

在一般连表操作中,使用的也是left进行连表。

语法

SELECT * from1 LEFT JOIN2 on1.外键字段=表2.被外键字段;
SELECT1.1,表1.2,表2.1,... from1 LEFT JOIN2 on1.外键字段=表2.被外键字段;

连表显示所有列

SELECT * from student LEFT JOIN class on student.class_id=class.id;

执行结果

Mysql查询语句之连表查询和增删改查语句补充

选择指定列查询

SELECT student.id,student.`name`,class.title from student LEFT JOIN class on student.class_id=class.id;

执行结果

Mysql查询语句之连表查询和增删改查语句补充

其实这和where连表是一样的。

方式三,inner连表

inner和left是差不多的,只不过left是正向连表,inner是反向连表。

就像学生表和课程表。

如果是通过学生表连课程表,属于正向,用left。

如果是通过课程表连学生表,就属于反向,用inner。

如果反向连表硬生生用left,会出现一些空值现象。

inner语法同left,只不过是表的前后顺序不一样。

其他操作

上述所有的操作,都属于查询操作,基本上入门是可以的,下面咱们来看一下剩下的增,删,改操作。

增(insert)

单条插入

语法

INSERT INTO 表(列名1,列名2,...) values(值1,值2,...);

添加一条学生信息

INSERT into student(name,age,gender,class_id) VALUES("吴彦祖",22,"男",1);

执行结果

Mysql查询语句之连表查询和增删改查语句补充

表内容

Mysql查询语句之连表查询和增删改查语句补充

多条插入

语法

INSERT INTO 表(列名1,列名2,...) values(值1,值2,...),(值1,值2,...);

批量添加学生信息

INSERT INTO student (NAME, age, gender, class_id)
VALUES
    ("范冰冰", 18, "女", 2),
    ("成龙", 24, "男", 3);

执行结果

Mysql查询语句之连表查询和增删改查语句补充

表内容

Mysql查询语句之连表查询和增删改查语句补充

改(update)

语法

UPDATE <表> set 列 = 值 where <条件>;

将李四的年龄修改成88岁

UPDATE student set age = 88 where name = "张三"

执行结果

Mysql查询语句之连表查询和增删改查语句补充

删除(delete)

语法

delete from <表名>
delete from <表名> where <条件>

删除张三

DELETE from student where name="张三"

执行结果

Mysql查询语句之连表查询和增删改查语句补充

总结

这章有点像收尾部分,补充了连表查询,后续又补充了Mysql的增删改查。

连表查询要区分一下left和inner的区别,一个是正向连,一个是反向连。

插入数据可以插入单条数据和多条数据,多跟参数即可。

如果在操作过程中有任何问题,记得下面留言,我们看到会第一时间解决问题。

越努力,越幸运。

我是码农星期八,如果觉得还不错,记得动手点赞一下哈。

感谢你的观看。

如何来理解Python中的字典数据类型

大家好,我是IT共享者,人称皮皮。今天给大家讲解下Python中的字典数据类型。

一、前言

字典是Python中的数据类型,可让将数据存储在键/值对中。

二、什么是字典理解?

字典理解是创建字典的一种优雅简洁的方法。

字典理解优化

使用字典理解优化函数。

例:

# 字典理解例:
square_dict = {num: num*num for num in range(1, 11)}
print(square_dict)

运行结果:

注·:

创建了square_dict带有数字平方键/值对的字典。但是,使用字典理解可以使在一行中创建字典。

三、使用字典理解

字典理解的最小语法为:

dictionary = {key: value for vars in iterable}

1. 图解析语法

让将此语法与上例中的字典理解进行比较。

2. 案例

如何使用字典理解

例:

#item price in dollars
old_price = {'milk': 1.02, 'coffee': 2.5, 'bread': 2.5}


dollar_to_pound = 0.76
new_price = {item: value*dollar_to_pound for (item, value) in old_price.items()}
print(new_price)

输出结果

注:

可以看到以美元为单位检索商品价格并将其转换为英镑。使用字典理解使此任务更加简单和短。

四、字典理解中的条件

可以通过添加条件来进一步自定义字典理解。让来看一个实例。

案例

1. 如果条件字典理解

例:

original_dict = {'jack': 38, 'michael': 48, 'guido': 57, 'john': 33}


even_dict = {k: v for (k, v) in original_dict.items() if v % 2 == 0}
print(even_dict)

输出结果

可以看到,由于if字典理解中的子句,仅添加了具有偶数值的项目。

2. 多重if条件字典理解

例:

original_dict = {'jack': 38, 'michael': 48, 'guido': 57, 'john': 33}


new_dict = {k: v for (k, v) in original_dict.items() if v % 2 != 0 if v < 40}
print(new_dict)

输出结果

在这种情况下,仅奇数值小于40的项目已添加到新字典中。

这是因为if字典理解中有多个子句。等效于and必须同时满足两个条件的操作。

3. if-else条件字典理解

例:

original_dict = {'jack': 38, 'michael': 48, 'guido': 57, 'john': 33}


new_dict_1 = {k: ('old' if v > 40 else 'young')
    for (k, v) in original_dict.items()}
print(new_dict_1)

输出结果

在这种情况下,将通过子典理解来创建新字典。

价值大于等于40的商品的值为“old”,而其他商品的值为“young”。

五、嵌套字典理解

可以将字典理解本身添加到字典理解中以创建嵌套字典。

案例

具有两个字典理解的嵌套字典

例:

dictionary = {
    k1: {k2: k1 * k2 for k2 in range(1, 6)} for k1 in range(2, 5)
}
print(dictionary)

输出结果

注:

在嵌套字典中构造了一个乘法表,用于2到4的数字。每当使用嵌套字典理解时,Python都会首先从外部循环开始,然后再进入内部循环。

六、使用字典理解的优势

如所见,字典理解大大缩短了字典初始化的过程。

它使代码更具pythonic风格,在的代码中使用字典理解可以缩短代码行,同时保持逻辑完整。

七、总结

本文基于Python基础,介绍了如何使用字典。通过分类对每一模块,进行详细的讲解。使用图解析语法,实例代码演示,运行效果图的展示,能够帮读者更好的理解。

在实际案例中遇到的问题,提供了一些有效的解决方案。使用Python语言,能够更直观的,加深读者对内容的理解。

代码很简单,希望能够帮助你更好的学习。

Python矩阵和Numpy数组的那些事儿

大家好,我是IT共享者,人称皮皮。今天给大家介绍矩阵和NumPy数组。

一、什么是矩阵?

使用嵌套列表和NumPy包的Python矩阵。矩阵是一种二维数据结构,其中数字按行和列排列。

二、Python矩阵

1. 列表视为矩阵

Python没有矩阵的内置类型。但是,可以将列表的列表视为矩阵。

例:

A = [[1, 4, 5], 
    [-5, 8, 9]]

可以将此列表的列表视为具有2行3列的矩阵。

如图:

2. 如何使用嵌套列表。

A = [[1, 4, 5, 12], 
    [-5, 8, 9, 0],
    [-6, 7, 11, 19]]


print("A =", A) 
print("A[1] =", A[1])      # 第二行
print("A[1][2] =", A[1][2])   # 第二行的第三元素
print("A[0][-1] =", A[0][-1])   # 第一行的最后一个元素
column = [];        # 空 list
for row in A:
  column.append(row[2])   


print("3rd column =", column)

当运行程序时,输出为:

三、NumPy数组

1. 什么是NumPy?

NumPy是用于科学计算的软件包,它支持强大的N维数组对象。

在使用NumPy之前,需要先安装它。

2. 如何安装NumPy?

如果使用Windows,使用PyCharm 安装NumPy,NumPy它带有一些其他与数据科学和机器学习有关的软件包。

成功安装了NumPy,就可以导入和使用它。

NumPy提供数字的多维数组(实际上是一个对象)。

例 :

import numpy as np
a = np.array([1, 2, 3])
print(a)               # 输出: [1, 2, 3]
print(type(a))         # 输出: <class 'numpy.ndarray'>

NumPy的数组类称为ndarray。

注:

NumPy的数组类称为ndarray。

3. 如何创建一个NumPy数组?

有几种创建NumPy数组的方法。

3.1 整数,浮点数和复数的数组

import numpy as np


A = np.array([[1, 2, 3], [3, 4, 5]])
print(A)


A = np.array([[1.1, 2, 3], [3, 4, 5]]) # 浮点数组
print(A)


A = np.array([[1, 2, 3], [3, 4, 5]], dtype = complex) # 复数数组
print(A)

运行效果:

3.2 零和一的数组

import numpy as np


zeors_array = np.zeros( (2, 3) )
print(zeors_array)
ones_array = np.ones( (1, 5), dtype=np.int32 ) // dtype
print(ones_array)      # 输出: [[1 1 1 1 1]]

在这里,指定dtype了32位(4字节)。因此,该数组可以采用从到的值。-2-312-31-1

3.使用arange()和shape()

import numpy as np


A = np.arange(4)


print('A =', A)


B = np.arange(12).reshape(2, 6)


print('B =', B)

四、矩阵运算

两个矩阵相加,两个矩阵相乘以及一个矩阵转置。在编写这些程序之前,使用了嵌套列表。让看看如何使用NumPy数组完成相同的任务。

两种矩阵的加法

使用+运算符将两个NumPy矩阵的对应元素相加。

import numpy as np


A = np.array([[2, 4], [5, -6]])
B = np.array([[9, -3], [3, 6]])
C = A + B      # 元素聪明的加法
print(C)

两个矩阵相乘

为了将两个矩阵相乘,使用dot()方法。

注意:用于数组乘法(两个数组的对应元素的乘法),而不是矩阵乘法。

import numpy as np


A = np.array([[3, 6, 7], [5, -3, 0]])
B = np.array([[1, 1], [2, 1], [3, -3]])
C = A.dot(B)
print(C)

矩阵转置

使用numpy.transpose计算矩阵的转置。

import numpy as np


A = np.array([[1, 1], [2, 1], [3, -3]])
print(A.transpose())

注:

NumPy使的任务更加轻松。

五、案例

1. 访问矩阵元素

与列表类似,可以使用索引访问矩阵元素。让从一维NumPy数组开始。

import numpy as np
A = np.array([2, 4, 6, 8, 10])


print("A[0] =", A[0])     # First element     
print("A[2] =", A[2])     # Third element 
print("A[-1] =", A[-1])   # Last element

运行该程序时,输出为:

现在,让看看如何访问二维数组(基本上是矩阵)的元素。

import numpy as np


A = np.array([[1, 4, 5, 12],
    [-5, 8, 9, 0],
    [-6, 7, 11, 19]])


#  First element of first row
print("A[0][0] =", A[0][0])  


# Third element of second row
print("A[1][2] =", A[1][2])


# Last element of last row
print("A[-1][-1] =", A[-1][-1])

当运行程序时,输出将是:

2. 访问矩阵的行

import numpy as np


A = np.array([[1, 4, 5, 12], 
    [-5, 8, 9, 0],
    [-6, 7, 11, 19]])


print("A[0] =", A[0]) # First Row
print("A[2] =", A[2]) # Third Row
print("A[-1] =", A[-1]) # Last Row (3rd row in this case)

当运行程序时,输出将是:

3. 访问矩阵的列

import numpy as np


A = np.array([[1, 4, 5, 12], 
    [-5, 8, 9, 0],
    [-6, 7, 11, 19]])


print("A[:,0] =",A[:,0]) # First Column
print("A[:,3] =", A[:,3]) # Fourth Column
print("A[:,-1] =", A[:,-1]) # Last Column (4th column in this case)

当运行程序时,输出将是:

注:

使用NumPy(而不是嵌套列表)可以更轻松地处理矩阵,而且甚至都没有涉及基础知识。建议详细研究NumPy软件包,尤其是当尝试将Python用于数据科学/分析时。

六、总结

本文基于Python基础,介绍了矩阵和NumPy数组,重点介绍了NumPy数组,如何去安装NumPy模块,如何去创建一个NumPy数组的两种方式。

通过案例的分析,代码的演示,运行效果图的展示,使用Python语言,能够让读者更好的理解。

读者可以根据文章内容,自己实现。有时候看到别人实现起来很简单,但是到自己动手实现的时候,总会有各种各样的问题,切勿眼高手低,勤动手,才可以理解的更加深刻。

代码很简单,希望对你学习有帮助。

手机自动化测试IDE—–Airtest实战篇

大家好,我是IT共享者,人称皮皮。上篇文章我们介绍了

手机自动化测试IDE —– 手把手教你用Airtest模拟器来连接手机,这篇我们来讲讲Airtest实际操作方法,一起来看看吧。

前言

前面我们讲到了Airtest的基础知识,手机自动化测试IDE—–Airtest基本操作方法,手机自动化测试IDE —– Airtest的安装和IDE控件详解,今天我们就来说说Airtest的具体操作方法吧,让我们轻松实现软件自动化,真正解放我们的双手吧。

基本操作

我们就是用我们说的跨平台API模块中的方法来操作我们的APK,下面来看下吧。我们先点击Touch,然后框选App所在的区域,如图:

这里框选好了后就会在脚本编辑器中自动生成代码了,如图:

这里就相当于点击了拼多多这个App了。当然这里只是给大家讲了一个例子,我们真正来做开发时,可以选择一些短视频软件,比如抖音,微视,快手等下面我们就以抖音为主来讲解下具体操作流程。

1.点击目标APP并等待界面加载完毕

我们要做自动点击肯定不能只是点击App就完事了啊,还有每个APP启动后的时间都不固定,我们肯定得等APP启动完毕之后我们才可以进行下一步操作,那么这样怎样做呢?我们以短视频软件微视为主,下面请看:

我们先点击微视,打开微视有两种方法,如下:

1).根据图像识别来打开

上面的这种方法就是根据图像识别来打开的。使用这种方法你要打开的APP必须在当前页,不可在其它页,否则搜索不到。

2).根据包名打开

这里我们首先需要获取到所有的包名,然后找到微视的包名,如下;

dev=device()  # 先获取到当前设备对象,即是Android对象
print(dev.list_app())  # 平台接口列表
start_app('com.tencent.weishi')#利用包名打开微视

喜欢哪种方法就用哪种方法。建议用第一种,因为有时候包名太多不好找。

2.点赞评论关闭

由于刚刚微视崩溃了,所以这里采用抖音短视频,这里我们需要将需要打开的APP的图像截取下来,先等到它在这篇区域出现然后点击才能进行其它操作 ,如下:

然后就是输入评论,输完后关闭评论,最后退出。

这样我们就实现了打开抖音视频并且给视频点赞和评论,然后关闭抖音回到桌面。这里有个小技巧分享给大家,就是大家在点击某一个区域的图像时记得先Wait一下哦,因为如果Wait的话如果你直接点击的话就会报错了。

3.截屏加滑动屏幕

如果想要捕捉操作截图的话,可以使用Snapshot进行截图,记得指定绝对地址哦。如下:

snapshot(filename=r'C:\Users\Administrator\Desktop\test.jpg',msg='截图成功')

成功截图了;然后我们给它添加个滑动视频的动作,因为我们不知道我们鼠标此时所处的位置的坐标的值是多少,所以我们需要开启Airtest中的一项重要功能—-实时坐标显示。设置方法如下图所示:

第二个代码补全对于电脑配置好的可以开启,电脑配置太差不建议开启。

可看到鼠标的坐标了。然后我们需要使用Swipe的帮助,有了它我们可以进行滑动屏幕的操作了,如下:

这行代码是我通过截取视频中两个地方的图像然后才得到的方法参数,这里是向量位移的操作。我们可以看到我们进行了这么多操作,但是都是一些图片,而且图片有的大有的小,看着不美观,我们其实可以将这些图片转换为代码,如下:

只需选中图片代码模式切换即可,我们所截取的图片都在这个文件里,大家可以去看看就知道了。其实这个就是PY文件里的内容。

4.不断滑动屏幕

那么重点来了,我们该如何将它重复一直滑动了,很简单,死循环,顺便给它加个随机延时。

import random


wait(Template(r"tpl1594203055954.png", record_pos=(0.356, 0.562), resolution=(1080, 2340)))
sleep(1)


touch(Template(r"tpl1594203066034.png", record_pos=(0.354, 0.564), resolution=(1080, 2340)))
sleep(2)
exists(Template(r"tpl1594203382253.png", record_pos=(0.415, 0.139), resolution=(1080, 2340)))
sleep(2)
snapshot(filename=r'C:\Users\Administrator\Desktop\test.jpg',msg='截图成功')
sleep(2)
assert_exists(Template(r"tpl1594203920118.png", record_pos=(0.411, 0.33), resolution=(1080, 2340)), "请填写测试点")


while True:#死循环,不断滑动短视频
    aa=random.randint(1,5)
    swipe((700,1950),(700,300))
    sleep(aa)

我们也可以在这个死循环里加入其它的操作,比如点赞,评论啥的,上面我都有说到,大家可以结合试试。

总结

通过对Airtest框架的学习,我们就能轻松做出短视频的点赞评论滑动以及其它功能,很多互粉的小盆友需要的正是这种神器了。

我是皮皮,如果觉得文章不错,记得三连噢,大家有问题也可以点击下方的图片,加我好友,交个朋友也好呀~

手机自动化测试IDE —– 手把手教你用Airtest模拟器来连接手机

大家好,我是IT共享者,人称皮皮。上篇文章讲了Airtest的安装和IDE控件详解相关知识,手机自动化测试IDE—–Airtest基本操作方法、手机自动化测试IDE —– Airtest的安装和IDE控件详解,这篇文章来给大家分享用Airtest模拟器来连接手机。

前言

也许有人觉得抓手机的数据包都费劲,还搞什么自动化,而且肯定不简单。但我要告诉你的是,这一切都被一个叫Airtest的自动化测试软件给搞定了,你只需要把它一直运行着,你的手机上的所有操作,就都交给它了,直接就是点点点。

连接设备

1.模拟器手机连接Airtest

这里我们需要连接手机,由于小编有模拟器,为了不影响小编玩手机,所以我决定用Airtest模拟器来连接手机,打开模拟器,选择关于平板电脑,如图:

连击多次版本号,直到出现开发者选项功能,然后打开开发者选项下的USB调试,如图:

这样我们就开启了USB调试,下面我们Airtest来远程连接我们的模拟器,如图:

这里有一个知识需要向大家说明的就是,我们连接的远程端口号不是随便弄的,而是根据模拟器的不同而使用的不同的端口号,模拟器和端口号一一对应关系如下:

这样选择好我们的主机地址和端口号后就可以进行连接了,然后我们点击connect就可以直接连接了,如图:

由于我们是使用模拟器连接,所以图上第一项最好选上,不然模拟器即使连接上了也是没有画面的。如果还是没有画面,那可能是因为屏幕捕捉程序“yosemite.apk”没有下载到模拟器中,在Airtest中找出来,直接拖动到模拟器中,再次连接模拟器,打开一看,如图:

成功连接上了。下面就上面三个选项跟大家简单描述下:

use javacap:#解决IDE中手机画面黑屏的问题
use ADB orientation :#解决IDE中屏幕旋转的问题
use ADB touch:#解决IDE中屏幕无法点击的问题

2.连接WIndows桌面应用

这里我们不光可以和模拟器建立连接,还可以和我们已打开或者未打开的应用进行连接操作,我们可以点击选定窗口,选择指定的应用程序,这样程序就会被加载到Airtest中去了,这里我打开了360浏览器,如图:

可以看到被加载进去了,我们可以在里面浏览了,但是此时我们的桌面上的浏览器却不翼而飞,这就是因为Airtest正在使用我们的浏览器,当我们点击断开当前设备就可以关闭掉这个设备,此时便可以重新看到浏览器又回到了我们的桌面了,如图:

2.Android真机连接Airtest

虽然模拟器很方便,但是毕竟很麻烦,而且万一你的电脑配置不行的话,那么模拟器可能开不了几个应用就爆了,所以这里我们也要使用手机来连接Airtest,手机相比其它的连接方式略显复杂,下面请看我表演。

1).设置开发者相关选项

首先我们需要将数据线插入电脑的USB接口,然后还是打开开发者选项和USB调试;只不过手机可不像模拟器,除了以上选项要设置之外,我们还需要设置默认USB配置,并把它设为MIDI,默认USB配置就在USB调试的下方,如图:

然后选择MIDI,如图:

这样手机端的开发者选项设置算是全部完结了,但是这样还是远远不够的,你还需要一大堆操作,是的,没错,一大堆,这款IDE最大的毛病就在这,正是验证了一句话,安装两小时,编程两分钟,哈哈哈哈。

2).安装手机相关驱动程序

因为小编手机是Vivo的,所以小编在网上下了一个Vivo的驱动程序包,如果你的手机跟小编不是一个版本,那么请看下面:

三星: http://www.samsung.com/cn/support/downloads
华为: http://consumer.huawei.com/minisite/HiSuite_cn/
小米: http://bigota.d.miui.com/tools/xiaomi_usb_driver.rar
Vivo: http://zs.vivo.com.cn/download.php
魅族:http://care.meizu.com/
一加:http://service.oneplus.cn/
华硕: http://www.asus.com.cn/support/
联想: http://www.lenovocare.com.cn/default.aspx
LG: http://www.lg.com/us/support/software-firmware-drivers
索尼: https://developer.sony.com/develop/drivers/
摩托罗拉: https://mobilesupport.lenovo.com/us/en/solution/MS88481
HTC: http://www.htc.com/us/software/htc-sync-manager/
谷歌: https://developer.android.com/studio/run/win-usb.html
黑莓: https://swdownloads.blackberry.com/Downloads/entry.do?code=4EE0932F46276313B51570F46266A608
戴尔: http://www.dell.com/support/home/us/en/04/Products?app=drivers&lwp=rt
宏基: https://www.acer.com/ac/en/US/content/drivers

如果上面还是没有,那么你可能需要一款兼容所有设备的驱动软件,驱动人生或者驱动精灵,随意挑选一个即可。

3).配置输入法和模拟位置

如果我们在Airtest中要输入文字的话,使用手机自带的输入法是没办法输入的,必须使用我们前面提到的“yosemite”输入法,这里在我们安装好手机的驱动后会自动下载到你的手机的,你只需要安装即可。如图:

然后我们再设置系统默认输入法为这个输入法即可,如图:

虽然设置好了后我们可以输入文字了,但是有时候的话可能鼠标点击的不是很准确,那么这个时候,我们还需要设置模拟位置,同样在开发者选项中,如图:

这样设置好后,回到我们的Airtest主界面,我们就可以看到已经出现了设备的名称和状态了,如图:

4).连接设备

还是如模拟器一样,点击Connect 勾选Use Javacap,这时设备就已经成功连接上了,如图:

5).无线连接Android真机

这里我们无需准备数据线也可以连接上我们的安卓机,只要你三个步骤完成好了,就简单了。我们首先需要知道安卓真机的IP地址,可在这里查看,如图:

然后我们使用这个IP地址在Airtest中建立连接,如图:

注意这里的端口号是5555,如果你写其它的端口的话也可以运行,但是它是无法监听TCP/IP信息的,如果你想指定多个这样的端口,命令提示符输入如下命令即可:

adb tcpip 666#开启666端口

这里有个前提,就是手机必须和我们IDE所处在同一个Wifi网络环境下才行,否则是访问不到的。

6).使用脚本连接

这里我们双击脚本编辑窗,设置一个编辑器的脚本文件,如下:

设置完毕后返回即可看到如下画面:

然后我们就可以在这里面连接安卓机了,具体代码如下:

connect_device('Android://127.0.0.1:5037/手机IP地址:5555')#前面是本机号和端口后面就是你手机的IP地址了

请大家注意,这里同样需要安卓机子和IDE处在同一个WiFi网络环境下哦。

总结

今天我们讲的是这款自动化工具的安装和界面功能的剖析,这个工具整体上来说,用法比较简单,就是安装坑太多,新手小白可能要花一些时间才能整明白,在此特与大家分享,愿大家学习之路更加平坦顺畅。下次我们再来讲讲IDE的妙用。

手机自动化测试IDE—–Airtest基本操作方法

大家好,我是IT共享者,人称皮皮。这篇我们来讲讲手机自动化测试IDE—–Airtest。

前言

前面我们讲到了Airtest的界面和安装技巧,今天我们就来说说Airtest的具体操作方法吧,让我们轻松实现软件自动化,真正解放我们的双手吧。

一、基本API介绍

我们在做自动化脚本的时候,每个生成的脚本文件会给我们自动生成一些代码,如图:

手机自动化测试IDE-----Airtest基本操作方法

这里所导入的模块其实就是跨平台的API,除了跨平台的API还有平台特定的API,比如:

airtest.core.android #安卓平台
airtest.core.ios   #苹果平台
airtest.core.win   #Windows平台

这里我们来详细说说这些模块。

1.跨平台API模块

这里我们要介绍的第一个就是跨平台模块:

from airtest.core.api import * #导入所有方法

1).初始化设备

这里初始化设备我们也有两种方案,下面请看:

1)).根据设备的UUID来初始化

语法格式:

init_device(platform='Android',uuid='',cap_method=JAVACAP for Android)
#平台 – Android,IOS或Windows
#uuid –目标设备的uuid,例如,用于Android的serialno,用于Windows的handle,用于iOS的uuid
#kwargs –可选的平台特定关键字args,例如cap_method = JAVACAP for Android

下面我们来列举一下实例,如下:

init_device(platform='Android',uuid='127.0.0.1:62001',cap_method='JAVACAP')
2)).根据设备的URL来初始化

语法格式如下:

android:///   连接当前安卓设备
android://adbhost:adbport/serial NO.?cap_method=javacap&touch_method=adb
windows:///    连接本地桌面程序
ios:///     连接IOS设备

这里我们主要是传入了ADB地址,端口和连接的夜神模拟器的序列号而连接上的。具体例子如下:

connect_device('android://127.0.0.1:5037/127.0.0.1:62001?cap_method=javacap&touch_method=adb')

2).返回当前活动设备

device()
手机自动化测试IDE-----Airtest基本操作方法

3).设置当前活动设备

有时候如果我们连接了多个设备,我们需要切换的话,就是用这个函数来达到目的,可以使用设备的索引或者设备的序列号来进行切换哦。

set_current(0)
set_current('127.0.0.1:62001')

4).运行环境配置

auto_setup(basedir = None,devices = None,logdir = None,project_root = None,compress = 0 )
basedir 设置当前脚本的所在位置,__file__也可以。
devices 指定运行脚本的设备以列表形式存在
logdir 设置脚本运行时的日志保存路径,默认为None,设为True可保存
project_root  设置api的项目根目录

5).开启并执行远程Shell命令

shell(cmd) #ls / data / local / tmp

6).在设备上启动程序

start_app('启动的应用程序包名')

7).在设备上停止程序

stop_app('启动的应用程序包名')

8).清除设备上的应用程序数据

clear_app('启动的应用程序包名')

9).在设备上安装应用程序

install(filepath='要在目标设备上安装的文件的路径')

10).在设备上卸载应用程序

uninstall('应用程序包名')

11).截图并保存到文件中

snapshot(filename='1.jpg',msg='hello',quality=3)
filename:图片名
msg:屏幕截图的简短描述
quality:图像质量,范围为[1,99]的整数

12).唤醒并解锁设备

wake('设备')

13).返回目标设备的主屏幕

home('设备')

14).设备屏幕上执行点击,滑动,捏,按键,输入操作

click(v=Template(x,y),times=2) #单击
v:触摸目标,可以是Template实例,也可以是绝对坐标(x,y)
times:执行多少次触摸


double_click() #双击
swipe(v1,v2)#滑动起点和终点
swipe(v1,vector=(x,y))#沿向量移动,向量可以是坐标也可以是屏幕百分比
#返回值:原点位置和目标位置


pinch()#捏操作,相当于缩放,参数如下:
in_or_out:放大或缩小
center:默认为None表示屏幕中心
percent:捏动作的屏幕比例,默认值为0.5 
keyevent(keyname='Home')#按键操作


text('文本')#在设备上输入文本

15).睡眠,等待

sleep(2)#睡眠两秒,延迟两秒
wait(v,timeout,interval,intervalfunc)#等待与设备屏幕上的模板匹配
v:等待的目标对象
timeout:超时时间
interval:尝试找到匹配项的时间间隔(秒)
intervalfunc:在每次未成功尝试找到相应匹配项后调用
返回值:匹配目标的坐标

16).检查给定目标在设备屏幕上是否存在

exists(v)
v:检查对象
如果找不到目标,则为False,否则返回目标的坐标

17).在设备屏幕上查找所有出现的目标并返回其坐标

find_all(v)
v:寻找目标
返回坐标列表

18).断言操作

assert_exists(v,msg) #断言目标存在于设备屏幕上
assert_not_exists(v,msg) #断言目标在设备屏幕上不存在
v:要检查的目标
msg:断言的简短描述


assert_equal(v1,v2,msg) #断言两个值相等
assert_not_equal(v1,v2,msg) #断言两个值不相等
v1:第一个值
v2:第二个值
msg:断言的简短描述

这里基本上我们就把使用方法说完了,下面我们来进行下实际操作,下一篇文章即将奉上。

二、总结

这篇文章主要介绍了Airtest的基本操作方法,可以让我们轻松实现软件自动化,下一篇文章将带大家一起进行实际操作,敬请期待!

我是皮皮,如果觉得文章不错,记得三连噢。

浅析Python模块的引入和调用

大家好,我是IT共享者,人称皮皮。这篇文章我们来浅析Python模块的引入和调用。

一、前言

Python中的模块,有过C语言编程经验的朋友都知道在C语言中如果要引用sqrt函数,必须用语句#include引入math.h这个头文件,否则是无法正常进行调用的。

那么在Python中,如果要引用一些其他的函数,该怎么处理呢?

在Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Java中的包很类似,比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块。

说的通俗点 :模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块。

二、模块引入

1. import

在Python中用关键字import来引入某个模块,比如要引用模块math,就可以在文件最开始的地方用import math来引入。

形如 :

 import module1,mudule2...

当解释器遇到import语句,如果模块在当前的搜索路径就会被导入。

在调用math模块中的函数时,必须这样引用:

  模块名.函数名

为什么必须加上模块名调用呢?

因为可能存在这样一种情况:在多个模块中含有相同名称的函数,此时如果只是通过函数名来调用,解释器无法知道到底要调用哪个函数。所以如果像上述这样引入模块的时候,调用函数必须加上模块名。

   import math


    #这样会报错
    print sqrt(2)


    #这样才能正确输出结果
    print math.sqrt(2)

有时候我们只需要用到模块中的某个函数,只需要引入该函数即可,此时可以用下面方法实现:

   from 模块名 import 函数名1,函数名2....

不仅可以引入函数,还可以引入一些全局变量、类等。

注意:

  1. 这种方式引入的时候,调用函数时只能给出函数名,不能给出模块名,但是当两个模块中含有相同名称函数的时候,后面一次引入会覆盖前一次引入。也就是说假如模块A中有函数function( ),在模块B中也有函数function( ),如果引入A中的function在先、B中的function在后,那么当调用function函数的时候,是去执行模块B中的function函数。

2. 如果想一次性引入math中所有的东西,还可以通过from math import 来实现

2. from…import

Python的from语句让你从模块中导入一个指定的部分到当前命名空间中。

语法如下:

   from modname import name1[, name2[, ... nameN]]

例如,要导入模块fib的fibonacci函数,使用如下语句:

   from fib import fibonacci

注意:

  • 不会把整个fib模块导入到当前的命名空间中,它只会将fib里的fibonacci单个引入。

3. from … import *

把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:

   from modname import *

注意:

  • 这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。

4 . 定位模块

当你导入一个模块,Python解析器对模块位置的搜索顺序是:

  1. 当前目录
  2. 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录。
  3. 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/
  4. 模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。

三、as 的三种用法

1. with…as…

第一种是和with结合使用,主要用于文件的读写操作,省去了关闭文件的麻烦。

写法:

with open("文件路径","读写方式") as 赋值变量:
    #  执行代码块

实例:

#test.py
with open("1.txt") as f:
    print f.read()


#1.txt(两个文件在同一目录下)

运行结果:

 

2. 导入模块起别名

导入模块是对模块进行重命名,也就是给模块起一个别名。示例代码在下方的第三点有演示。

3. except结合使用

第一种:给traceback模块起别名为a

示例代码 :

import traceback as a
try:
    while 1/0 < 0:
        print True

第二种:和except组合使用,将捕获到的异常对象赋值给e。

实例代码 :

except Exception as e:
    print "e=",e
    a.print_exc()

四、总结

本文详细的讲解了Python基础 ( 模块 )的引入,调用 。介绍了常用的三种模块。模块时的需要注意的事项,以及在实际操作中会遇到的问题,提供了解决方案。希望可以帮助你更好的学习Python。