标签归档:开发

教你如何在 Windows 下让崩溃的 Python 程序自动重启

我们用Python定时跑一些自动化程序的时候会出现程序崩溃的情况。此时如果你本人不在电脑面前,或者没有留意到程序的崩溃,没有及时重新拉起程序,会造成或大或小的损失。那么我们如何在 Windows 下让崩溃的 Python 程序自动重启呢?答案是通过 Supervisor-win.

本文将教你如何在 Windows 下使用 Supervisor-win 重新拉起崩溃的Python程序。

1.准备

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

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

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

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

pip install supervisor-win

如果你出现 “DLL load failed: 找不到指定的程序” 的报错,请重新安装pywin32:

pip install pywin32==223

2.Windows Python程序自动重启的配置

接下来,你需要编写一个让你的Python程序自动运行,遇到报错自动重启的配置:

[program:cancel]
command=G:\\Anaconda3\\envs\\tdx_easytrader\\python.exe D://CODE//tdx_easytrader//dataserver.py
    
[supervisord]
nodaemon=true

[supervisorctl]

前两行就是你的程序运行命令,在上面的例子中,program: 后面的关键词是你自定义的程序名,我的Python位于 G:\Anaconda3\envs\tdx_easytrader\python.exe,我想要自重启的脚本位于 D://CODE//tdx_easytrader//dataserver.py

此外,后面的三行是必须配置的,按我的默认写法即可。

编写完成后将配置命名为 supervisord.conf 保存于任何地方,可以是项目目录下,也可以是一个重要的配置目录文件夹。

然后执行以下命令启动 supervisord:

supervisord -c D:\CODE\tdx_easytrader\supervisord.conf

注意 -c 参数后就是你的 supervisord.conf 的绝对路径。启动完毕显示:

2022-06-27 19:58:54,809 INFO process group added: 'cancel'
2022-06-27 19:58:54,810 INFO supervisord started with pid 28472
2022-06-27 19:58:54,815 INFO Spawned: 'cancel' with pid 27220
2022-06-27 19:58:55,830 INFO success: cancel entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

意思是,supervisord 进程已经启动,pid为28472。我命名为cancel的Python进程也已经启动,pid为27220。我们在任务管理器中可以查看到这两个进程:

3.测试

接下来我们测试一下它能否自动重启,让我们强杀 27220 这个进程,观察终端:

2022-06-27 19:58:54,815 INFO Spawned: 'cancel' with pid 27220
2022-06-27 19:58:55,830 INFO success: cancel entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2022-06-27 20:02:58,077 INFO exited: cancel (exit status 1; not expected)
2022-06-27 20:02:58,590 INFO Spawned: 'cancel' with pid 16640
2022-06-27 20:02:59,603 INFO success: cancel entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

可以看到, 20:02:58秒的时候 cancel 程序意外退出(exit status 1; not expected),然后supervisord重新帮我们拉起了一个cancel程序,pid为16640:

测试成功,程序成功自重启。

Supervisor不仅会把日志输出到终端中,在你运行命令的目录中,它还会生成supervisord.log, 这里面也保存了所有运行日志:

当然,在上方我们supervisord的配置里,你也能配置日志输出位置、最大大小、分片数量等:

[supervisord]
logfile = /tmp/supervisord.log
logfile_maxbytes = 50MB
logfile_backups=10
loglevel = info
pidfile = /tmp/supervisord.pid

Supervisord 还有许多其他的功能,有兴趣的同学可以访问他们官网查询:

http://supervisord.org/introduction.html

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

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

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


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

超实用!yfinance 教你 Python 获取并下载美股数据

yfinance 是一个使用 Yahoo! 获取数据的 Python 第三方模块。它支持获取最细到1分钟级的历史数据及股票基本面数据,是免费获得美股分钟级及以上粒度数据的不二之选。

1.准备

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

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

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

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

pip install yfinance

2.yfinance 基本使用

通过yfinance你可以使用一样命令下载任意美股股票的数据,比如:

import yfinance as yf

# 单股
data = yf.download("AAPL", start="2017-01-01", end="2017-04-30")
#                  Open       High        Low      Close  Adj Close     Volume
# Date
# 2017-01-03  28.950001  29.082500  28.690001  29.037500  27.257641  115127600
# 2017-01-04  28.962500  29.127501  28.937500  29.004999  27.227135   84472400
# 2017-01-05  28.980000  29.215000  28.952499  29.152500  27.365593   88774400
# 2017-01-06  29.195000  29.540001  29.117500  29.477501  27.670671  127007600
# 2017-01-09  29.487499  29.857500  29.485001  29.747499  27.924126  134247600
# ......

# 多股
data = yf.download("SPY AAPL", start="2017-01-01", end="2017-04-30",
                   group_by="ticker")
#                  AAPL                                   ...         SPY
#                  Open       High        Low      Close  ...         Low       Close   Adj Close     Volume
# Date                                                    ...
# 2017-01-03  28.950001  29.082500  28.690001  29.037500  ...  223.880005  225.240005  205.509079   91366500
# 2017-01-04  28.962500  29.127501  28.937500  29.004999  ...  225.610001  226.580002  206.731735   78744400
# 2017-01-05  28.980000  29.215000  28.952499  29.152500  ...  225.479996  226.399994  206.567459   78379000
# 2017-01-06  29.195000  29.540001  29.117500  29.477501  ...  225.899994  227.210007  207.306549   71559900
# ......

默认是获取天级别的数据,如果你需要获取分钟级的,只需要添加interval参数:

import yfinance as yf

# 单股
data = yf.download("AAPL", start="2022-05-18", end="2022-05-23", interval="1m")
print(data)

#                                  Open        High         Low       Close   Adj Close   Volume
# Datetime
# 2022-05-17 12:00:00-04:00  148.000000  148.050003  147.839996  147.865005  147.865005        0
# 2022-05-17 12:01:00-04:00  147.869507  147.919998  147.779999  147.889893  147.889893   123746
# 2022-05-17 12:02:00-04:00  147.889999  147.929993  147.750000  147.907394  147.907394    92847
# 2022-05-17 12:03:00-04:00  147.904999  147.929993  147.785004  147.839996  147.839996    79266
# 2022-05-17 12:04:00-04:00  147.839996  147.895004  147.779999  147.860001  147.860001    58905
# ......

它支持的分钟级参数有:1m,2m,5m,15m,30m,60m,90m等等

此外还支持小时级和天线、周线、月线级别:1h,1d,5d,1wk,1mo,3mo等等

获取到的数据类型就是Dataframe,因此你还可以直接保存为csv文件:

# 公众号:Python 实用宝典
import yfinance as yf

data = yf.download("AAPL", start="2022-05-18", end="2022-05-23", interval="1m")
data.to_csv("aapl_20220518_20220523.csv")
# 保存到本地,命名为 aapl_20220518_20220523.csv

3.通过yfinance获取股票基本数据

如果你需要获取一只股票的基本数据,如市值、市盈率、股息等,你可以通过定义一只股票的Ticker,利用其info属性获取:

# 公众号:Python 实用宝典
import yfinance as yf

aapl = yf.Ticker("aapl")
print(aapl.info)
# {'zip': '95014', 'sector': 'Technology', 'fullTimeEmployees': 154000, 'longBusinessSummary': 'Apple ......

这个字典比较长,这里省略显示了,里面包含了比如市盈率(PE)等信息:

# 公众号:Python 实用宝典
import yfinance as yf

aapl = yf.Ticker("aapl")
aapl.info['forwardPE']
# 20.974085

你还可以获取每次派息数据:

# 公众号:Python 实用宝典
import yfinance as yf

aapl = yf.Ticker("aapl")
print(aapl.dividends)
# Date
# 1987-05-11    0.000536
# 1987-08-10    0.000536
# 1987-11-17    0.000714
# 1988-02-12    0.000714
# 1988-05-16    0.000714
#                 ...
# 2021-05-07    0.220000
# ...             ...

获取资产负债表:

# 公众号:Python 实用宝典
import yfinance as yf

aapl = yf.Ticker("aapl")
print(aapl.balancesheet)
#                              2021-09-25    2020-09-26    2019-09-28    2018-09-29
# Total Liab                 2.879120e+11  2.585490e+11  2.480280e+11  2.585780e+11
# Total Stockholder Equity   6.309000e+10  6.533900e+10  9.048800e+10  1.071470e+11
# Other Current Liab         5.357700e+10  4.786700e+10  4.324200e+10  3.929300e+10
# Total Assets               3.510020e+11  3.238880e+11  3.385160e+11  3.657250e+11
# Common Stock               5.736500e+10  5.077900e+10  4.517400e+10  4.020100e+10
# ......

现金流数据:

# 公众号:Python 实用宝典
import yfinance as yf

aapl = yf.Ticker("aapl")
print(aapl.cashflow)
#                                              2021-09-25    2020-09-26    2019-09-28    2018-09-29
# Investments                               -2.819000e+09  5.335000e+09  5.809300e+10  3.084500e+10
# Change To Liabilities                      1.400200e+10 -1.981000e+09 -2.548000e+09  9.172000e+09
# Total Cashflows From Investing Activities -1.454500e+10 -4.289000e+09  4.589600e+10  1.606600e+10
# ......

新闻数据:

# 公众号:Python 实用宝典
import yfinance as yf

aapl = yf.Ticker("aapl")
print(aapl.news)
# [{'uuid': '476a41c6-c6dc-3050-9b8f-c3777c8485b2', 'title': "Dow Jones Futures Rise After 'Hard' Reality Hits Market; What To Do Now", 'publisher': "Investor's Business Daily", 
# 'link': 'https://finance.yahoo.com/m/476a41c6-c6dc-3050-9b8f-c3777c8485b2/dow-jones-futures-rise-after.html', 
# 'providerPublishTime': 1653305573, 'type': 'STORY'}, {'uuid': '721d466d-5394-3f3c-a9c3-b0920d44c7f3' ......

总之,有了yfinance这个神器,除了高频数据你无法获取之外,其他的美股数据你都能获取得到,有需要的小伙伴可以试试,非常好用。

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

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

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


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

专属Python开发者的完美终端工具—Rich

Rich 是一个 Python 库,可以为你在终端中提供富文本和漂亮、精美的格式。

使用 Rich API 可以很容易的在终端输出添加各种颜色和不同风格。它可以绘制漂亮的表格,进度条,markdown,突出显示语法的源代码及回溯等等,优秀的功能不胜枚举。

我已经将本文全部示例存放在网盘中,在Python实用宝典公众号后台回复 rich示例 可以下载全部示例。

1.Rich 兼容性

Rich 适用于 Linux,OSX 和 Windows。可与新的 Windows 终端一起使用,Windows 的经典终端仅限 8 种颜色。

Rich 还可以与Jupyter NoteBook一起使用,而无需其他配置。

2.Rich 安装说明

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

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

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

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

pip install rich

3.Rich 的 Print 功能

想毫不费力地将 Rich 的输出功能添加到你的Python脚本程序中,你只需导入 rich print 方法,该方法和其他 Python 的自带功能的参数类似。 你可以试试:

from rich import print

print("Hello, [bold magenta]World[/bold magenta]!", ":vampire:", locals())

可以看到,基于 rich 的 print 方法输出的内容都是带颜色、带重点的,相比于Python自带的 print 有明显的优势。

4.自定义 Console 控制台输出

想要对 Rich 终端内容进行更多的自定义设置,你需要导入并构造一个控制台对象:

from rich.console import Console

console = Console()

Console 对象含有一个 print 方法,它的界面与 python 内置的 print 功能相似。你可以试试:

console.print("Hello", "World!")

你可能已经料到,这时终端上会显示“ Hello World!”,请注意,与内置的“打印”功能不同,Rich 会将文字自动换行以适合终端宽度。

有几种方法可以为输出添加自定义颜色和样式。你可以通过添加 style 关键字参数来为整个输出设置样式。例子如下:

console.print("Hello", "World!", style="bold red")

输出如下图:

这个范例一次只设置了一行文字的样式。如果想获得更细腻更复杂的样式,Rich 可以渲染一个特殊的标记,其语法类似于 bbcode。示例如下:

console.print("Where there is a [bold cyan]Will[/bold cyan] there [u]is[/u] a [i]way[/i].")

5.Console 控制台记录

Console 对象具有一个 log() 方法,该方法具有与 print() 类似的界面,除此之外,还能显示当前时间以及被调用的文件和行。

默认情况下,Rich 将针对 Python 结构和 repr 字符串进行语法突出显示。如果你记录一个集合(如字典或列表),Rich 会把它漂亮地打印出来,使其切合可用空间。下面是其中一些功能的示例:

from rich.console import Console
console = Console()

test_data = [
    {"jsonrpc": "2.0", "method": "sum", "params": [None, 1, 2, 4, False, True], "id": "1",},
    {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
    {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": "2"},
]

def test_log():
    enabled = False
    context = {
        "foo": "bar",
    }
    movies = ["Deadpool", "Rise of the Skywalker"]
    console.log("Hello from", console, "!")
    console.log(test_data, log_locals=True)


test_log()

以上范例的输出如下:

注意其中的 log_locals 参数会输出一个表格,该表格包含调用 log 方法的局部变量。

log 方法既可用于将长时间运行应用程序(例如服务器)的日志记录到终端,也可用于辅助调试。

Logging 处理程序

你还可以使用内置的处理类来对 Python 日志记录模块的输出进行格式化和着色。下面是输出示例:

6. 表情符号

将名称放在两个冒号之间即可在控制台输出中插入表情符号。示例如下:

>>> console.print(":smiley: :vampire: :pile_of_poo: :thumbs_up: :raccoon:")
😃 🧛 💩 👍 🦝

请谨慎地使用此功能。

7.表格

Rich 包含多种边框,样式,单元格对齐等格式设置的选项。下面是一个简单的示例:

from rich.console import Console
from rich.table import Column, Table

console = Console()

table = Table(show_header=True, header_style="bold magenta")
table.add_column("Date", style="dim", width=12)
table.add_column("Title")
table.add_column("Production Budget", justify="right")
table.add_column("Box Office", justify="right")
table.add_row(
    "Dev 20, 2019", "Star Wars: The Rise of Skywalker", "$275,000,000", "$375,126,118"
)
table.add_row(
    "May 25, 2018",
    "[red]Solo[/red]: A Star Wars Story",
    "$275,000,000",
    "$393,151,347",
)
table.add_row(
    "Dec 15, 2017",
    "Star Wars Ep. VIII: The Last Jedi",
    "$262,000,000",
    "[bold]$1,332,539,889[/bold]",
)

console.print(table)

该示例的输出如下:

请注意,控制台标记的呈现方式与 print() 和 log() 相同。实际上,由 Rich 渲染的任何内容都可以添加到标题/行(甚至其他表格)中。

Table 类很聪明,可以调整列的大小以适合终端的可用宽度,并能根据需要做文本环绕的处理。下面是相同的示例,输出与比上表小的终端上:

8.进度条

Rich 可以渲染多个不闪烁的进度条形图,以跟踪长时间运行的任务。

基本用法:用 track 函数调用程序并迭代结果。下面是一个例子:

from rich.progress import track

for step in track(range(100)):
    do_step(step)

添加多个进度条并不难。以下是效果示例:

这些列可以配置为显示你所需的任何详细信息。

内置列包括完成百分比,文件大小,文件速度和剩余时间。下面是显示正在进行的下载的示例:

它可以在显示进度的同时下载多个 URL。要自己尝试一下,请参阅示例文件中的 examples/downloader.py ,在Python实用宝典公众号后台回复 rich示例下载全部示例。

9.按列输出数据

Rich 可以将内容通过排列整齐的,具有相等或最佳的宽度的来呈现。下面是(macOS / Linux)ls 命令的一个非常基本的克隆,用列来显示目录列表:

import os
import sys

from rich import print
from rich.columns import Columns

directory = os.listdir(sys.argv[1])
print(Columns(directory))

以下屏幕截图是列示例的输出,该列显示了从 API 提取的数据:

10.Markdown

Rich 可以呈现markdown,相当不错的将其格式显示到终端。

为了渲染 markdown,请导入 Markdown 类,将其打印到控制台。例子如下:

from rich.console import Console
from rich.markdown import Markdown

console = Console()
with open("README.md") as readme:
    markdown = Markdown(readme.read())
console.print(markdown)

该例子的输出如下图:

11.语法突出显示

Rich 使用 pygments 库来实现语法高亮显示。用法类似于渲染 markdown。构造一个 Syntax 对象并将其打印到控制台。下面是一个例子:

from rich.console import Console
from rich.syntax import Syntax

my_code = '''
def iter_first_last(values: Iterable[T]) -> Iterable[Tuple[bool, bool, T]]:
    """Iterate and generate a tuple with a flag for first and last value."""
    iter_values = iter(values)
    try:
        previous_value = next(iter_values)
    except StopIteration:
        return
    first = True
    for value in iter_values:
        yield first, False, previous_value
        first = False
        previous_value = value
    yield first, True, previous_value
'''
syntax = Syntax(my_code, "python", theme="monokai", line_numbers=True)
console = Console()
console.print(syntax)

输出如下:

12.错误回溯(traceback)

Rich 可以渲染漂亮的错误回溯日志,比标准的 Python 回溯更容易阅读,并能显示更多代码。

你可以将 Rich 设置为默认的回溯处理程序,这样所有异常都将由 Rich 为你呈现。

下面是在 OSX(与 Linux 类似)上的外观:

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

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

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


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