标签归档:Python

You-get 万能的音视频下载工具

You-Get 是一个使用Python开发的小型命令行实用程序,可以通过一行命令直接从Web下载媒体内容(视频,音频,图像)等,不用任何配置。

这款工具支持的站点特别多,比如Youtube、优酷、腾讯视频、网易云音乐、Ted、知乎等等主流网站,可以说几乎是万能的,在本文最下方的附录可查看You-Get支持的完整网站列表。

下面是这个万能工具的使用指南。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install you-get

2.使用方法

使用的时候直接在命令行输入:

you-get 媒体链接

就能将媒体内容下载在当前命令行输出的文件夹中,比如下载网易云音乐的歌曲:
https://music.163.com/#/song?id=1811118551

不仅如此,下载B站的视频,它连多part视频都能一并下载:

第一次下载的时候,它会提示这是个多part视频,后缀添加–playlist下载全部part视频:

令人惊喜的是,这个工具在下载视频的同时将弹幕数据也下载了:

弹幕文件通过 danmu2ass 这样的工具处理后,就可以将弹幕数据格式化为ass文件,用播放器播放视频的时候,将ass格式的弹幕文件导入到播放器,就能完美复现B站的体验效果。

知乎的下载比较特别,只支持下载回答和专栏内出现的视频:

3.增值功能

3.1 暂停和继续下载

没错,这个工具支持断点续传,这是为了防止出现下载的视频太长,用户中途停止导致前面下载的内容报废的问题。

1.暂停下载:按 Ctrl+C 可以中断命令,下载目录下会保存有一个以 .download 为扩展名的缓存文件。

2.继续下载:重新执行相同的命令下载任务,如果下载目录下有上次下载保存的缓存文件,则继续上次下载进度。

3.强制重新下载(即使下载完成也会重新写入),带 -f 参数即可:

you-get -f https://www.bilibili.com/video/BV137411n7hY

3.2 选择视频格式和清晰度

用过 -i 参数能获得当前视频所有的清晰度和格式:

拿到格式名称后,如果你想下载高清 1080P的视频,只需要带–format参数就可以下载指定格式的视频:

you-get --format=dash-flv https://www.bilibili.com/video/BV137411n7hY

3.3 本地播放器直接播放网络视频

这也是一个相当强力的特性,如果你受不了网页播放器那些简单的功能,想加一些比如调整屏幕比例为2.35:1之类的自己本地播放器的功能,那你可以尝试这样做:

1.在资源管理器中打开 你的播放器的 安装目录
2.按住Shift并在空白处右击鼠标,选择在此处打开 Powershell 窗口
3.输入下面的 You-Get 播放命令即可

you-get -p 你的播放器.exe https://www.bilibili.com/video/BV1Fa4y1a7jE

3.4 代理设置

你如果有下载油管之类的视频的需求,那么可能需要设置代理才可以下载成功,you-get 也提供了这样的选项:

you-get -x 127.0.0.1:8087 'https://www.youtube.com/watch?v=jNQXAC9IVRw'

-x 参数后接代理的 IP:端口号,再将需要下载的视频链接放到后面就可以了,非常方便。

3.5 设置下载文件的路径

如果你不想把文件下载到当前命令行所处的文件夹中,那么可以用 -o 参数指定下载目录:

you-get -o C:\Users\83493\Downloads 'https://www.bilibili.com/video/BV1Fa4y1a7jE'

大体功能就是这些,相信已经能够覆盖大家的日常使用范围了,喜欢的话请在下方点个赞或者在看让更多的人看到吧!

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

附录:

SiteURL视频图像音频
YouTubehttps://www.youtube.com/
Twitterhttps://twitter.com/
VKhttp://vk.com/
Vinehttps://vine.co/
Vimeohttps://vimeo.com/
Veohhttp://www.veoh.com/
Tumblrhttps://www.tumblr.com/
TEDhttp://www.ted.com/
SoundCloudhttps://soundcloud.com/
SHOWROOMhttps://www.showroom-live.com/
Pinteresthttps://www.pinterest.com/
MTV81http://www.mtv81.com/
Mixcloudhttps://www.mixcloud.com/
Metacafehttp://www.metacafe.com/
Magistohttp://www.magisto.com/
Khan Academyhttps://www.khanacademy.org/
Internet Archivehttps://archive.org/
Instagramhttps://instagram.com/
InfoQhttp://www.infoq.com/presentations/
Imgurhttp://imgur.com/
Heavy Music Archivehttp://www.heavy-music.ru/
Freesoundhttp://www.freesound.org/
Flickrhttps://www.flickr.com/
FC2 Videohttp://video.fc2.com/
Facebookhttps://www.facebook.com/
eHowhttp://www.ehow.com/
Dailymotionhttp://www.dailymotion.com/
Coubhttp://coub.com/
CBShttp://www.cbs.com/
Bandcamphttp://bandcamp.com/
AliveThaihttp://alive.in.th/
interest.mehttp://ch.interest.me/tvn
755
ナナゴーゴー
http://7gogo.jp/
niconico
ニコニコ動画
http://www.nicovideo.jp/
163
网易视频
网易云音乐
http://v.163.com/
http://music.163.com/
56网http://www.56.com/
AcFunhttp://www.acfun.cn/
Baidu
百度贴吧
http://tieba.baidu.com/
爆米花网http://www.baomihua.com/
bilibili
哔哩哔哩
http://www.bilibili.com/
豆瓣http://www.douban.com/
斗鱼http://www.douyutv.com/
凤凰视频http://v.ifeng.com/
风行网http://www.fun.tv/
iQIYI
爱奇艺
http://www.iqiyi.com/
激动网http://www.joy.cn/
酷6网http://www.ku6.com/
酷狗音乐http://www.kugou.com/
酷我音乐http://www.kuwo.cn/
乐视网http://www.le.com/
荔枝FMhttp://www.lizhi.fm/
懒人听书http://www.lrts.me/
秒拍http://www.miaopai.com/
MioMio弹幕网http://www.miomio.tv/
MissEvan
猫耳FM
http://www.missevan.com/
痞客邦https://www.pixnet.net/
PPTV聚力http://www.pptv.com/
齐鲁网http://v.iqilu.com/
QQ
腾讯视频
http://v.qq.com/
企鹅直播http://live.qq.com/
Sina
新浪视频
微博秒拍视频
http://video.sina.com.cn/
http://video.weibo.com/
Sohu
搜狐视频
http://tv.sohu.com/
Tudou
土豆
http://www.tudou.com/
阳光卫视http://www.isuntv.com/
Youku
优酷
http://www.youku.com/
战旗TVhttp://www.zhanqi.tv/lives
央视网http://www.cntv.cn/
Naver
네이버
http://tvcast.naver.com/
芒果TVhttp://www.mgtv.com/
火猫TVhttp://www.huomao.com/
阳光宽频网http://www.365yg.com/
西瓜视频https://www.ixigua.com/
新片场https://www.xinpianchang.com/
快手https://www.kuaishou.com/
抖音https://www.douyin.com/
TikTokhttps://www.tiktok.com/
中国体育(TV)http://v.zhibo.tv/
http://video.zhibo.tv/
知乎https://www.zhihu.com/

升级 Flask 到 Quart, 3 倍性能提升就这么简单!

简评:将你的 Flask 应用程序升级到 Quart 应用程序,轻松获得 3 倍的性能提升。

自从 Flask 在 8 年前发布以来,Python 发生了很大变化,特别是引入了 asyncio之后。asyncio 允许开发像 uvloop 和 asyncpg 这样的库来大大提高性能,可惜要 Flask 集成 asyncio 或这些库并不是一件简单的事情。不过不用气馁,Quart 框架与 asyncio 可以一起使用 Flask-API。

基于共享的 Flask-API,现有的 Flask 应用程序进行很少的修改就可以变成 Quart 应用程序,然后就可以使用这些新的库来实现 Flask 无法做到的性能优化。

本文详细介绍了典型的生产环境的 CRUD 应用程序从 Flask 到 Quart 的转换,并展示相关的性能改进优势。

0. 我想直接看杰伦

将这个 Flask-pyscopg2 应用程序升级到 Quart-asyncpg 应用程序可以提高 3 倍的性能,而且不需要对代码进行重大的重写或调整。

如上所示,在针对单个资源详情的请求下,Flask每秒请求为330个,而quart能达到1160个。以此类推,Quart 相比于 Flask 平均性能提高3倍。

这个比较,我使用了一个简单的只提供一个 RESTful 接口的应用程序,这是微服务架构中的常见用例。

该应用程序有三个路由。这些路由分别是:

  • 单个电影详情:GET /films/pk/
  • 所有电影:GET /films/
  • 添加新评论:POST /reviews/

源代码可以在以下网址找到:
https://github.com/pgjones/faster_than_flask_article

有两个 commit ,分别是一个 Flask 版本和一个Quart 版本。

1. 从 Flask 到 Quart

从 Flask 改用 Quart 很容易,只需要一点点改变,特别是 from flask 改为 from quart,函数变成异步函数。

def add_review():
  data = request.get_json()
  ...

变成

async def add_review():
  data = await request.get_json()
  ...

2.数据库连接,从 psycopg2 到 asyncpg

从 psycopg2 改用 asyncpg 比较麻烦,因为两者有不同的用法。

为了简化区别,我们在 Flask 应用程序中使用了 PoolWrapper,使得 psycopg2 可以使用与 asyncpg 相同的 API 进行上下文管理,即:

with pool.acquire() as connection:

这将允许通过with更改为async with来使用asyncpg。

当然,除了连接之外,Asyncpg和psycopg2还在游标使用、事务、执行参数和查询格式方面存在差异。这些差异是你在迁移过程中需要注意的。

3.部署

Flask 应用程序往往不能直接在生产环境中直接暴露给用户,这是因为Flask 本身一次只能处理一个请求。因此,常常用WSGI服务器与某种异步 worker 结合使用,例如  带 eventlet 的Gunicorn。

Quart 也可以用 Gunicorn 部署,它允许使用相同的命令来运行 Flask 和 Quart 应用程序:

$ gunicorn --config gunicorn.py 'run:create_app()'
针对 Flask 和 Quart 的性能测试是基于 Gunicorn 进行的。

4.添加测试数据

除了添加一个简单的 review 表之外,Postgresql 示例数据库还要为应用程序提供一些用于 CRUD的数据。

CREATE TABLE review (
  film_id INTEGER REFERENCES film(film_id),
  rating INTEGER
);

5.性能测试

为了测量应用程序的性能,我们使用了wrk。它被配置为使用20个连接,以匹配数据库连接池的大小(确保最高的吞吐量,20是我使用过的典型值)。命令如下:

测试 GET 请求的命令是

$ wrk --connections 20 --duration 5m http://localhost:5000/${PATH}/

测试 POST 请求的命令是

$ wrk --connections 20 --duration 5m --script post.lua http://localhost:5000/${PATH}/

测试使用的 post.lua 文件如下:

wrk.method = "POST"
wrk.body = '{"film_id": 995, "rating": 4}'
wrk.headers["Content-Type"] = "application/json"

6.系统信息与结果

系统信息:

Postgres (9.5.10),wrk (4.0.0),Python (3.6.3),asyncpg (0.13.0),Flask (0.12.2),Gunicorn (19.7.1),psycopg2 (2.7.3.2), Quart (0.3.1)

全部运行在一台 AWS c4.large 机器上。

结果

请注意,Quart 服务器的平均等待时间减少了 2 至 3.5 倍,每秒的请求数量增加了 2 至 3.5 倍。

7.结论

Flask 应用程序升级到 Quart 应用程序是相当简单的,因为大部分 API 是共享的,所以主要工作就是在正确的位置写asyncawait。然而,如果使用 SQLAlchemy(或其他 ORM),则从psycopg2 到 asyncpg 的改变会比较复杂,并且可能会很麻烦。

这个 demo 应用程序的性能显着提高,这个改进主要是由于 Quart 使用了 asyncpg 和 uvloop,据估计,仅 Quart 就能提供 1.5 倍的提升。

总之,从 Flask-psycopg2 应用程序升级到 Quart-asyncpg 应用程序的比较简单,并拥有非常合理的性能改进。这可能会扩展到其他基于 asyncio 的库,意味着将 Flask 应用程序转换到 asyncio 生态系统,Quart 只需要很小的工作量。

原文:3x faster Flask apps
https://hackernoon.com/3x-faster-than-flask-8e89bfbe8e4f

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python编写的超帅数独可视化解题器

数独相信大家都玩过,它被称为“聪明人的游戏”,在很多人眼里:

会玩数独=高智商

为什么?因为数独能够培养观察力,提高反应力: 数独的练习能够锻炼手眼脑的协调性、提高手脑并用的能力,锻炼大脑的思维灵活度,全面提高反应力。

非常适合孩子在成长过程中锻炼大脑,适合成年人在生活中激活思维。

不过当我们遇到不会解的数独怎么办?答案是,用Python算出来!

基于 Pygame-Sudoku-Solver 这个开源项目,可视化解决数独问题变得极其简单。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

1.在终端输入以下命令下载该开源库

git clone https://github.com/tymscar/Pygame-Sudoku-Solver.git

2.使用cd命令进入该文件夹,并安装依赖:

cd Pygame-Sudoku-Solver
pip install -r requirements.txt

接下来,可以试试运行该项目了:

python solver.py

此时会出现一个空白3*3的九宫格

2.怎么解题

这个开源项目的解题方法如下:

1.输入题目数字 — 你只需要点击空白区域,此时会回显绿色方块,输入数字,如果数字合法则会填入框内,如果不合法则会闪现红色。

2.当你将数独题目里的所有数字填写完毕,单击空格键即可开始运算:

而且,细心的作者还帮大家准备了夜晚模式,单击“d”键可切换到夜晚模式:

3.原理

所有的解题源代码都放在了solver.py文件中,大家可以在里面看到整个解题过程。

作者没有写任何注释,但是代码逻辑思路是清晰的,比如核心判断逻辑,Cell类里的 isValid, 用于判断某个值 (what变量) 放进某个 Cell 里是否合法:

此处,lineV.cells 表示数组中每一列组成的cell;lineH.cells即每一行组成的cell;box.cells即每个子九宫格。他们都有一个共同的特点:其中不能出现重复的值。

因此你会看到如果某个值存在于这些cells当中,isValid直接返回False,表明其不应该出现在这个位置。

如果你的网络较差,git clone拿不到代码,可以在公众号后台回复:数独 下载源代码。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python制作国际空间站实时跟踪器

Open Notify是一个开源项目,旨在为NASA的一些出色数据提供简单的编程接口。

open-notify.org 的作者做了一些工作,以获取原始数据并将其转换为与太空和航天器有关的API

本文将通过这个接口,获取得到国际空间站的位置,并实时地绘制到地图上:

感谢cr0sis/Real-time-International-space-station-tracker

为了实现本文的目标,你得先安装ISS_Info:

pip install ISS-Info

下面分步骤讲解整套绘制流程

1.地图初始化

为了实时展示国际空间站的路径,需要使用turtle绘制曲线,因此可以创建一个turtle画布,将背景设为地球:

  
import ISS_Info
import turtle
import time
import json
import urllib.request

screen = turtle.Screen()
screen.setup(720,360)
screen.setworldcoordinates(-180,-90,180,90)
screen.bgpic("map.png")
screen.bgcolor("black")
screen.register_shape("isss.gif")
screen.title("Real time ISS tracker")

iss = turtle.Turtle()
iss.shape("isss.gif")

2.获取空间站的人数

如果能知道空间站上的宇航员人数,我们就能更加准确的跟踪国际空间站。幸运的是open-notify确实提供了这样的接口。

为了获取人数信息,我们必须向:
http://api.open-notify.org/astros.json
请求拿到数据,并将相应的宇航员名字写在左上角:

astronauts = turtle.Turtle()
astronauts.penup()
astronauts.color('black')
astronauts.goto(-178,86)
astronauts.hideturtle()
url = "http://api.open-notify.org/astros.json"
response = urllib.request.urlopen(url)
result = json.loads(response.read())
print("There are currently " + str(result["number"]) + " astronauts in space:")
print("")
astronauts.write("People in space: " + str(result["number"]), font=style)
astronauts.sety(astronauts.ycor() - 5)

people = result["people"]

for p in people:
    print(p["name"] + " on: " + p["craft"])
    astronauts.write(p["name"] + " on: " + p["craft"], font=style)
    astronauts.sety(astronauts.ycor() - 5)

3.绘制空间站位置

为了能够绘制空间站的实时位置,我们需要请求拿到空间站的位置信息。请求的接口是:
http://api.open-notify.org/iss-now.json

不过作者将其封装成了一个函数,我们直接调用 iss_current_loc 即可,循环获取国际空间站位置:

while True:  
    location = ISS_Info.iss_current_loc()
    lat = location['iss_position']['latitude']
    lon = location['iss_position']['longitude']
    print("Position: \n latitude: {}, longitude: {}".format(lat,lon))
    pos = iss.pos() 
    posx = iss.xcor()
    if iss.xcor() >= (179.1):           ### Stop drawing at the right edge of  
        iss.penup()                     ### the screen to avoid a 
        iss.goto(float(lon),float(lat)) ### horizontal wrap round line
        time.sleep(5)
    else:
      iss.goto(float(lon),float(lat))
      iss.pendown()
      time.sleep(5)

我们还可以标出自己目前所处的位置,以查看和国际空间站的距离及空间站经过你上空的时间点(UTC)。

# 深圳
lat = 112.5118928
lon = 23.8534489

prediction = turtle.Turtle()
prediction.penup()
prediction.color('yellow')
prediction.goto(lat, lon)
prediction.dot(5)
prediction.hideturtle()

url = 'http://api.open-notify.org/iss-pass.json?lat=' +str(lat-90) + '&lon=' + str(lon)
response = urllib.request.urlopen(url)
result = json.loads(response.read())

over = result ['response'][1]['risetime']

prediction.write(time.ctime(over), font=style) 

不过这里值得注意的是,iss-pass.json这个接口的纬度计算必须在-90到90之内,因此深圳的纬度需要减去90.

最终效果如下:

在Python实用宝典公众号后台回复“国际空间站”或者“ISS”即可获得本文完整源代码哦。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 凯利公式 — 最优投资本金计算

1955年,美国盛行答题积累奖金的电视节目,答题者通过连续答对题目来累计奖金池。而在电视外,庄家针对这个节目开设了答题者能否答对题目的赌盘,吸引了许多赌徒参与下注。

但是,节目在东海岸直播,西海岸则有直播延时,有赌徒便抓住了这个机会,利用延时提前通过电话得到了答题者答题情况,赶在西海岸直播前参与下注,从中套利。

受此启发,贝尔实验室的科学家约翰·拉里·凯利于1956年在《贝尔系统技术期刊》中提出了凯利公式:

“如果通信渠道的输入符号代表偶然事件的结果,在该偶然事件中,可以按照与其概率一致的赔率进行投注,那么一个赌徒就可以利用输入符号给他的信息,使他的钱以指数形式增长。”

论文中他以一个赛马模型提出了凯利公式的雏形:

其中:

f* = 应该放入投注的资本比值
p = 获胜的概率
q = 失败的概率
b = 赔率

举个例子,如果一个赌博你有60%的获胜率(p=0.6, q=0.4),并且赔率是1赔2(b=2),则赌客每次下注的资金是 40% (计算方式:(b*p-q)/b)

当然,当初提出这个公式的凯利其实是为了通信学研究的,并不是很贴近实际投资场景。不过,它有一个变形:

其中:

f* = 应该放入投注的资本比值
p = 获胜的概率
q = 失败的概率
rW = 净利润率
rL = 净损失率

这个公式很关键,因为它使得计算投资利润最大化的本金数额成为可能。比如说,使用我们之前的MACD量化投资策略:

Python 量化投资实战教程(2) —MACD策略

有1万元购买股票,10%的止盈点,10%的止损点,假设针对某只股票每次盈利的概率是7/8,此时rW=0.1, rL=0.1,那么每次交易我们应该投入 f=((7/8)*0.1 – (1/8)*0.1) / 0.1*0.1=7.5%。

也就是说,按照这个策略买股票,每次你只能投入本金的7.5%才能使利润获得最大化。

这个公式用Python来计算也非常简单:

def kelly(p, q, rW, rL):
    """
    计算凯利公式

    Args:
        p (float): 获胜概率
        q (float): 失败概率
        rW (float): 净利润率
        rL (float): 净亏损率

    Returns:
        float: 最大化利润的投资本金占比(%)
    """
    return (p*rW - q*rL)/(rW * rL)

基本就是把公式照搬下来计算。

凯利公式看起来真的很不错,不过,请大家注意了,量化投资中的获胜概率,比如我们上述计算中的盈利概率: 7/8,是基于某只股票的历史数据推测出来的,历史并不代表未来,因为未来是不可知的,我们只能说这只股票,在过去,表现的不错。

所以,模型永远只是一个近似的替代,并不能说明一切,凯利公式也是一样,如果凯利公式告诉你,要放大仓位,你可要三思,万一发生黑天鹅事件,分分钟教你做人,如果你还上了杠杆,那就要上人生最重要的一堂课了。

我们经常会认为凯利公式所针对投注比例是全资产,事实上,我更喜欢将凯利公式所针对的投注比例当做是你可承受损失的资产。

比如你有100万,你能承受10万的损失,那么这10万就能拿来根据凯利公式进行投资,因为这是最保险,能让你心情不那么痛苦的做法。

不要贪,很重要。

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 最好用的8个VS Code扩展

1. Python extension for Visual Studio Code

这个扩展是由微软官方提供的,支持但不仅限于以下功能:

  • 通过Pylint或Flake8支持代码检查
  • 在VS Code编辑器中调试代码
  • IntelliSense支持自动完成,代码导航和格式化。
  • 支持Jupyter Notebook,Pytest和Unittest
  • 在编辑器中轻松切换Python环境

2.Python Preview

这个插件很牛皮,能够实时可视化你的代码结果。

不仅如此,还能为VSCode切换各种主题皮肤。

3.Sort lines

这个扩展很有意思,可以给你按字母大小排序(升序、降序),也可以进行排序+去重。而且还能将所有文本打乱顺序。

做短文本分类的训练,清洗数据集的时候,这个工具大有用处。

4.Git Graph

这玩意可是Git神器,堪比Pycharm内的Git管理器。

通过这个扩展,可以清楚地看见当前分支的commit记录和变化,可以通过按钮的方式轻易地创建、切换分支、cherry pick、merge等操作。

对比分支、查看未提交的修改……还有许多可定制的扩展设置。

5.Python Snippets

很多时候,我们用到的代码片段都是类似的,比如for循环、try/catch等等,现在有了这个工具,我们只需要输入命令生成代码片段,然后再进行微调,就能完成功能的开发。

此外,有些时候我们可能会忘记某些内置函数的用法,这个工具也能给你提供示例代码做参考,而不用你再去搜索引擎搜索示例,实在非常方便。

6.Better Comments

这是一个让你能更好地编写注释的工具,它能根据关键词用不同的颜色高亮代码片段。支持以下类型的高亮:

1. 感叹号 “!” 代码警告。
2. 问号“?”代表存留疑问。
3. TODO 代码未来将要进行的操作。
4. @param 参数

此外,它还支持在设置中自定义需要高亮句子的首部关键词。

7.autoDocstring

这个扩展我应该已经推荐了好多次,能够自动生成函数的注释格式,通过tab键快速切换填充块编写相应的注释。

8.Python Indent

你有没有觉得VSCode里对Python的自动缩进有点不准确?甚至可以用“丑”来形容。每次我都喜欢强行矫正VSCode给我做的自动缩进。

经过一番查阅,我终于找到了能纠正VSCode缩进错误的扩展,它就是Python Indent,看看下面的示例,相信你也会安装它。

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 简单实用的日志装饰器

在写代码的时候,往往会漏掉日志这个关键因素,导致功能在使用的时候出错却无法溯源。

其实,只需要写一个非常简单的日志装饰器,我们就能大大提升排查问题的效率。

1.简陋版

写一个装饰器非常简单,因为本质上装饰器就是一个返回函数的“高阶”函数而已:

1.函数作为参数传递进装饰器。
2.装饰器内定义一个函数,处理作为参数传递进来的函数。
3.返回这个装饰器内定义的函数

import datetime


def log(func):
    """
    日志装饰器,简单记录函数的日志

    Args:
        func (function): 函数
    """
    def inner(*args):
        timestamp = str(datetime.datetime.now()).split(".")[0]
        res = func(*args)
        print(f"[{timestamp}] ({func.__name__}) {args} -> {res}")
        return res
    return inner

用一下试试看:

@log
def pluser(a, b):
    return a + b

pluser(1, 2)

效果如下:

虽然这样可以实现我们所需要的功能,但其实有很大的优化空间。

2.普通版

第一版代码中有一个显而易见的问题,装饰器内定义的处理函数不支持kwargs,而在装饰器中支持kwargs仅仅是举手之劳而已。

第二个问题是,生成时间戳的时候采用字符串截取的形式,这种形式过于粗暴。其实可以使用strftime做字符串转换。

修改如下:

import datetime


def log(func):
    """
    日志装饰器,简单记录函数的日志

    Args:
        func (function): 函数
    """
    def inner(*args, **kwargs):
        timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        res = func(*args, **kwargs)
        print(f"[{timestamp}] ({func.__name__}) {args} -> {res}")
        return res
    return inner

似乎优化地差不多了,不过依然存在改进空间。

3.优化版

在前两版代码中,我们使用print进行日志输出,其实这种处理日志的方式并不标准。

使用logging模块控制日志输出是一个更好地选择。

为了使用logging模块记录日志,我们需要先配置好logging相关的选项。

1.首先,生成一个日志记录器,并配置日志等级:

import logging

# 获取日志记录器,配置日志等级
logger = logging.getLogger(__name__)
logger.setLevel('DEBUG')

2.配置日志格式、增加handler控制输出流:

# 默认日志格式
formatter = logging.Formatter("%(asctime)s - [%(levelname)s] - %(message)s")
# 输出到控制台的handler
chlr = logging.StreamHandler()
# 配置默认日志格式
chlr.setFormatter(formatter)

此处可以设置handler所需要处理的日志等级,没有设置则默认使用logger自身的Level,即DEBUG等级。

3.最后,将此handler加入到日志记录器内:

# 日志记录器增加此handler
logger.addHandler(chlr)

logging 完整配置如下:

import logging

# 获取日志记录器,配置日志等级
logger = logging.getLogger(__name__)
logger.setLevel('DEBUG')

# 默认日志格式
formatter = logging.Formatter("%(asctime)s - [%(levelname)s] - %(message)s")
# 输出到控制台的handler
chlr = logging.StreamHandler()
# 配置默认日志格式
chlr.setFormatter(formatter)

# 日志记录器增加此handler
logger.addHandler(chlr)

使用的时候非常简单,就是把print换成logger.debug即可:

def log(func):
    """
    日志装饰器,简单记录函数的日志

    Args:
        func (function): 函数
    """
    def inner(*args, **kwargs):
        timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        res = func(*args, **kwargs)
        logger.debug(f"func: {func.__name__} {args} -> {res}")
        return res
    return inner

效果如下:

这样,一个比较完善的日志装饰器就完成了。

附常用的日志等级配置:

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Kafka入门及Kafka-Python初体验

本文介绍了以下内容:

1.什么是Kafka?

2.为什么我们需要使用Kafka这样的消息系统及使用它的好处

3.如何将Kafka使用到我们的后端设计中。

译自https://timber.io/blog/hello-world-in-kafka-using-python/,有部分删改。

1.Kafka是什么、为什么我们需要它?

简而言之,Kafka是一个分布式消息系统。这是什么意思呢?

想象一下,你现在有一个简单的Web应用,其包含了网页前端客户端(Client)、服务端和数据库:

你需要记录所有发生在你的Web应用的事件,比如点击、请求、搜索等,以便后续进行计算和运营分析。

假设每个事件都由单独的APP完成,那么一个简单的解决方案就是将数据存储在数据库中,所有APP连接到数据库进行存储:

这看起来简单,但是其中还会出现许多问题:

1.点击、请求、搜索等事件会产生大量的数据到数据库中,这可能会导致插入事件存在延迟。

2.如果选择将高频数据存储在SQL或MongoDB等数据库中,很难再原有历史数据的基础上扩展数据库。

3.如果你需要用这些数据进行数据分析,你可能无法直接对数据库进行高频率的读取操作。

4.每个APP可以遵循自己的数据格式,这就意味着当你需要在不同的APP进行数据交换时,你需要进行数据格式的转换。

通过使用像Kafka这样的消息流系统,可以很好地解决这些问题,因为他们可以执行以下操作:

1.存储的大量数据可以被持久化、校验和复制,具备容错能力。

2.支持跨系统实时处理连续的数据流。

3.允许APP独立发布数据或数据流,并与使用它的APP无关。

那么它和传统数据库有何不同?

尽管Kafka可以持久化地存储数据,但它不是数据库。

Kafka不仅允许APP存储或提取连续的数据流,还支持实时处理。这与对被动数据执行CRUD操作或对传统数据库执行查询的方式不同。

听起来不错,那么Kafka是如何解决以上挑战的?

Kafka是一个分布式平台,是为规模而构建的,这意味着它可以处理高频率的读写和存储大量数据。它确保数据始终可靠。它还支持从故障中恢复的强大机制。

以下是为什么应该使用Kafka的一些关键因素:

1.1 简化后端架构

在Kafka的帮助下,我们前面的结构会变得简单一些:

1.2 通用数据管道

如上所示,Kafka充当多个APP和服务的通用数据管道,这给了我们两个好处:

1.数据是集成的,我们将来自不同系统的数据都存在一个地方,这使得Kafka成为真正的数据源。任何APP都可以将数据推送到该平台,然后由另一个APP提取数据。

2.Kafka使得应用程序之间交换数据变得容易。因为我们可以标准化数据格式,减少了数据格式的转换。

1.3 通用连接性

尽管Kafka允许你使用标准数据格式,但并不意味着你的APP就不需要数据转换了,它只是减少了我们转换数据的频率罢了。

此外,Kafka提供了一个叫 Kafka Connect 的框架允许我们维护遗留的老系统。

1.4 实时数据处理

类似于监控系统这样的实时APP,往往需要连续的数据流,这些数据需要被立即处理或尽量减少延迟处理。

Kafka的流式处理,使得处理引擎可以在很短的时间内(几毫米到几分钟)内取数、分析、以及响应。

2.Kafka入门

2.1 安装

安装Kafka是一个相当简单的过程。只需遵循以下给定步骤:

1.下载最新的1.1.0版本的Kafka

2.使用以下命令解压缩下载文件: tar -xzf kafka_2.11-1.1.0.tgz

3.cd到Kafka目录开始使用它: cd kafka_2.11-1.1.0

2.2 启动服务器

ZooKeeper是一个针对Kafka等分布式环境的集中管理工具,它为大型分布式系统提供配置服务、同步服务及命名注册表。

因此,我们需要先启动ZooKeeper服务器,然后再启动Kafka服务器。使用以下命令即可:

# Start ZooKeeper Server
bin/zookeeper-server-start.sh config/zookeeper.properties

# Start Kafka Server
bin/kafka-server-start.sh config/server.properties

2.3 Kafka 基本概念

我们快速介绍一下Kafka体系结构的核心概念:

1.Kafka在一个或多个服务器上作为集群运行。

2.Kafka将数据流存储在名为topics的类别中。每条数据均由键、值、时间戳组成。

3.Kafka使用发布-订阅模式。它允许某些APP充当producers(生产者),记录数据并将数据发布到Kafka topic中。

同样,它允许某些APP充当consumer(消费者)和订阅Kafka topic并处理由它产生的数据。

4.除了Prodcuer API 和 Consumer API,Kafka还为应用提供了一个 Streams API 作为流处理器。通过 Connector API 我们可以将Kafka连接到其他现有的应用程序和数据系统。

2.4 架构

如你所见,每个Kafka的 Topic 可以分为多个Partition(分区),可以使用broker(经纪人)在不同的计算机上复制这些 Topic,从而使消费者可以并行读取 Topic.

kafka的复制是针对分区的:

比如上图中有4个broker, 1个topic, 2个分区,复制因子是3。当producer发送一个消息的时候,它会选择一个分区,比如topic1-part1分区,将消息发送给这个分区的leader, broker2、broker3会拉取这个消息,一旦消息被拉取过来,slave会发送ack给master,这时候master才commit这个log。

因此,整个系统的容错级别极高。当系统正常运行时,对Topic的所有读取和写入都将通过leader,且leader会保证所有其他broker均被更新。

如果Broker失效了,系统会自动重新配置,此时副本也可以接管成为Leader.

2.5 创建Kafka Topic

让我们创建一个名为 sample,含有一个partition(分区)和一个replica(副本)的Kafka Topic:

bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic sample

列出所有的Kafka Topics,检查是否成功创建了sample Topic:

bin/kafka-topics.sh --list --zookeeper localhost:2181

describe topics 命令还可以获得特定Topic的详细信息:

bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic sample

2.6 创建生产者与消费者

这里是代码实战部分,利用Kafka-Python实现简单的生产者和消费者。

1.首先需要安装kafka-python:

pip install kafka-python

2.创建消费者(consumer.py)

from kafka import KafkaConsumer
consumer = KafkaConsumer('sample')
for message in consumer:
    print (message)

3.创建生产者(producer.py)

现在,有一个消费者正在订阅我们的消息流,因此我们要创建一个生产者,发布消息到Kafka:

from kafka import KafkaProducer
producer = KafkaProducer(bootstrap_servers='localhost:9092')
producer.send('sample', b'Hello, World!')
producer.send('sample', key=b'message-two', value=b'This is Kafka-Python')

现在,你重新运行消费者(consumer.py),你就会接收到生产者发送过来的消息。

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应红色字体的验证信息,进入互助群询问。


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

网络IO谁更快?Python与Go请求速度对比

上一篇关于Python和Go的文章是:

什么?Python Celery 也能调度Go worker?

文中我们讨论了Python Celery调度Go写的worker的方法。

而在 优劣互补! Python+Go结合开发的探讨

一文中,我们讨论了Go在单线程计算性能上的优势。

现在,考虑这样的一种场景:

我们需要从某些网址中同步数据并进行计算,保存到本地redis缓存中。

现在,我们可以通过编写Go Worker的方式,将计算和保存的过程保存在本地的redis缓存中,然后使用Celery来调度这些任务。

问题在于,从这些网址中获取数据的步骤,写在Go Worker里是否合适?Go进行网络请求是否比Python更稳定、速度更快?今天我们就来比较一下。

1.同步比较

首先,试试Go语言请求百度,获得这个请求和拿到回应之间的时间差:

package main

import (
    "fmt"
	"time"
	"net/http"
)

func main() {

	t1 := time.Now()
    resp, err := http.Get("https://baidu.com")
	t2 := time.Now()
	
	fmt.Println("spend time:", t2.Sub(t1))
	
    if err != nil {
		fmt.Println("请求失败")
    }

    defer resp.Body.Close()
}

结果如下:

可以看到,平均耗时在250ms左右。

然后测试Python的requests模块请求网站:

import requests
import time
t1 = time.time()*1000
requests.get("https://baidu.com")
t2 = time.time()*1000
print(t2-t1)

平均约220ms,似乎在单个请求的情况下,Python略胜一筹。

但是单个请求的比较是没有意义的,因为这个差异可以忽略不计。

重点还是在下面并发请求的比较上。

2.并发比较

现在,我们试试用Go语言并发请求10次百度:

package main

import (
    "fmt"
	"time"
	"net/http"
    "sync"
)

func test_get() {
	http.Get("https://baidu.com")
}

func main() {
	var numbers = 10
    var wg sync.WaitGroup
    wg.Add(numbers)
	t1 := time.Now()
	for i := 0; i < numbers; i++ {
		go func() {
			test_get()
			wg.Done()
		}()
	}
	wg.Wait()
	t2 := time.Now()
	
	fmt.Println("spend time:", t2.Sub(t1))
}

效果如下:

平均消耗在300ms左右,和单次请求差不多,速度还是相当快的。

接下来试试Python的并发请求,值得注意的是,这里没有用requests模板,因为requests模块是同步的,这一点一定要注意。

因此在这里需要使用aiohttp进行并发请求:

import asyncio
import time
from aiohttp import ClientSession


async def request_web():
    async with ClientSession() as session:
        async with session.get("https://baidu.com"):
            pass
 
loop = asyncio.get_event_loop()
tasks=[]
for i in range(10):
    tasks.append(request_web())

t1 = time.time()*1000
loop.run_until_complete(asyncio.wait(tasks))
t2 = time.time()*1000
print(t2 - t1)

测试结果如下:

可以看到,平均耗时在500ms左右,在并发的时候,其速度相比于Go略逊一筹。

3.总结

可以看到,Python在单个请求的时候(使用requests模块)速度比Go稍微快一丢丢,但是这样的区别几乎可以忽略不计。

在并发10次请求的情况下,Go平均耗时300ms,而Python平均耗时500ms,Go略胜一筹。

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应的红字验证信息,进入互助群询问,请一定记得回复红字的问题,这样我才会拉你进群。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 量化投资实战教程(7)—孕线真的有用吗?

如上图就是所谓的孕线(harami)形态,也叫作子线跟随母线。两线长度差异越大,信号越强烈。

从技术指标层面来讲,在综合了其他指标(如20日均线、macd等)的情况下,孕线是比较可靠的反转信号。

从上图可以知道,孕线看涨信号主要由以下指标组成:

1.前一根K线的实体完全覆盖第二根K线
2.价格处于底部位置

今天我们就来试试用上述指标回测603186这只股票,看看效果如何。

​为了简化问题,卖出信号由买入股票后涨10%或跌10%决定。

本文全部代码,请在Python实用宝典后台回复:量化投资7 进行下载。或到Github获取:
https://github.com/Ckend/pythondict-quant

1.基础版

该策略最大的难点在于如何判断价格处于底部位置。

我们第一版策略可以根据前三天的股价来判断是否处于底部位置。

如果股价连续三天下跌,第四天出现孕线上涨信号,则视为可买入信号。

对此股票使用该策略进行回测,时间是2010年1月1日至2020年8月15日,效果如下:

部分代码如下:

盈利9次,亏损10次,平均收益率1.3%,效果比较一般。

从中的买入点可以看到,该策略并没有准确地找到价格底部位置,许多买入点都在高点买入了。

2.优化版

为了解决高点买入的问题,我们需要合理的判断价格是否处于底部。

【连续多日下跌】这样的指标是无法判断价格所处的位置的。

相比之下,X日价格平均线却有一定的参考意义,如果价格低于20日平均线,可以认为该股票正处于近期的价格低谷中,此时出现的孕线才有价值。

因此,我们将【连续三日下跌】的指标更换为【价格低于20日均线】,重新进行回测

效果如下:

上述部分代码修改为:

平均收益率4.7%,盈利8次,亏损6次。不错,相比于基础版已经有非常大的改进。

但是,从图像上看还是有可以改进的地方。

3.加强版

事实上,第二版中有些孕线的当日最高价或当日最低价已经超过了前一日的K线实体,最标准的孕线应该是整根K线都在前一日的K线的实体内。

因此harami的计算方法依然需要改进,但是,这种孕线一整根都在前一日的K线实体内的情况,在这只股票10年的发展里只出现过4次,当然,这4次里3次都盈利了:

部分代码如下:

平均收益率6.5%,但这种最标准的孕线出现次数实在太少了,其实并不具备参考价值。

因此整体来看,孕线是一个不可强求的指标。

如果你是一个传统的投资者,可能很久很久才能在你的股票池里遇到一次标准的孕线。

如果你是一个量化投资者,即便你通过回测的方法找到了今天A股中所有符合孕线标准的股票,由于历史数据较少,并不足以构成投资参考价值,毕竟抛五次硬币,四次朝上的可能性也是挺大的。

总的而言,不推荐将孕线作为投资参考指标。不过,本文的研究仅仅局限于一只股票,下篇量化投资实战文章,我们将围绕整个A股,对孕线的可用性进行探讨。

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典