我有一个需要无限期运行的脚本。该脚本设置为通过电子邮件向我发送每天已完成的某些步骤的确认信息。我正在尝试为此使用 smtplib。
初始连接已设置,以便我将在脚本启动时使用 getpass 输入我的登录名(写入脚本)和密码。我不想将我的密码写入脚本中,甚至不想让脚本在配置文件中引用。因此,我想在启动时输入密码并保留 smtp 连接。
按照脚本中的要求重新连接到 smtp 连接将无法完全脱离脚本并让它无限期运行。
我目前正在使用的示例代码如下所示:
import smtplib
import getpass
smtpObj = smtplib.SMTP('smtp.gmail.com',587)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login('myemail@gmail.com',password = getpass.getpass('Enter Password: '))
Run Code Online (Sandbox Code Playgroud)
然后我输入密码,输出是:
(235, b'2.7.0 Accepted')
Run Code Online (Sandbox Code Playgroud)
所以这一切正常。
问题是脚本需要根据时间暂停几分钟到几天不等。这是使用带有时间条件的 while 循环来实现的,直到调用发送函数的某个时间:
smtpObj.sendmail('myemail@gmail.com','recipient@gmail.com','This is a test')
Run Code Online (Sandbox Code Playgroud)
然而,经过大约 20/30 分钟的时间后,似乎(即,如果暂停就足够了)。然后 smptObj.sendmail 调用将由于超时错误而失败。
具体错误如下:
SMTPSenderRefused: (451, b'4.4.2 Timeout - closing connection. l22sm2469172wre.52 - gsmtp', 'myemail@gmail.com')
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经尝试了以下方法:
使用以下超时参数化实例化连接对象:
smtpObj = smtplib.SMTP('smtp.gmail.com',587,timeout=None)
smtpObj = smtplib.SMTP('smtp.gmail.com',587,timeout=86400)
Run Code Online (Sandbox Code Playgroud)
这些似乎都没有抑制连接的“超时”(即同样的问题仍然存在)。
我也尝试过这篇文章中建议的这种解决方案:
如何使用 smtplib 和 Python 打开 SMTP 连接?
然而,这也没有奏效!
我确实想尝试避免每次发送电子邮件时都必须重新连接的解决方案,因为我只想手动输入一次连接密码,而不是将其写入直接或间接编写脚本。
肯定有办法处理超时问题!如果有人可以在这里提供帮助,请告诉我!不过,如果您认为在脚本需要发送电子邮件之前重新连接的更“明显”解决方案是更好的方法,那么请告诉我。
谢谢!...
我有一个日期时间系列的 dtype:float64。我正在尝试将自定义函数应用于该系列的滚动窗口。我希望这个函数返回字符串。但是,这会生成 TypeError。为什么这会产生错误,有没有办法直接通过应用一个函数来使这个工作?
下面是一个例子:
import numpy as np
import pandas as pd
np.random.seed(1)
number_series = pd.Series(np.random.randint(low=1,high=100,size=100),index=[pd.date_range(start='2000-01-01',freq='W',periods=100)])
number_series = number_series.apply(lambda x: float(x))
def func(s):
if s[-1] > s[-2] > s[-3]:
return 'High'
elif s[-1] > s[-2]:
return 'Medium'
else:
return 'Low'
new_series = number_series.rolling(5).apply(func)
Run Code Online (Sandbox Code Playgroud)
结果是以下错误:
TypeError: must be real number, not str
Run Code Online (Sandbox Code Playgroud)
我目前采用的解决方法是修改 func 以将整数输出到一个系列,然后将另一个函数应用于该系列以生成新系列。按照下面的例子:
def func_float(s):
if s[-1] > s[-2] > s[-3]:
return 1
elif s[-1] > s[-2]:
return 2
else:
return 3
float_series = number_series.rolling(5).apply(func_float)
def func_text(s):
if s …
Run Code Online (Sandbox Code Playgroud) 我正在尝试通过条件选择从 Pandas DataFrame 返回特定项目(并且不想引用索引来这样做)。
下面是一个例子:
我有以下数据框:
Code Colour Fruit
0 1 red apple
1 2 orange orange
2 3 yellow banana
3 4 green pear
4 5 blue blueberry
Run Code Online (Sandbox Code Playgroud)
我输入以下代码来搜索蓝莓的代码:
df[df['Fruit'] == 'blueberry']['Code']
Run Code Online (Sandbox Code Playgroud)
这将返回:
4 5
Name: Code, dtype: int64
Run Code Online (Sandbox Code Playgroud)
这是类型:
pandas.core.series.Series
Run Code Online (Sandbox Code Playgroud)
但我真正想要返回的是类型的数字 5:
numpy.int64
Run Code Online (Sandbox Code Playgroud)
如果我输入以下代码,我可以这样做:
df[df['Fruit'] == 'blueberry']['Code'][4]
Run Code Online (Sandbox Code Playgroud)
即引用索引给出数字 5,但我不想引用索引!
我可以在此处部署另一种语法来实现相同的目的吗?
谢谢!...
更新:
另一个想法是以下代码:
df[df['Fruit'] == 'blueberry']['Code'][df[df['Fruit']=='blueberry'].index[0]]
Run Code Online (Sandbox Code Playgroud)
但是,这似乎不是特别优雅(并且它引用了索引)。是否有更简洁和精确的方法不需要引用索引,或者这是绝对必要的?
谢谢!...
在这一刻。每次我加载 Jupyter Notebook 并打算使用 Matplotlib 时,我都会为所有要内联输出的图表设置默认样式和大小。
例如:
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = [16,8]
plt.style.use('ggplot')
Run Code Online (Sandbox Code Playgroud)
这导致笔记本会话的其余部分具有一致的大小和样式。
但是,有没有办法使这些更改永久化,以便每次加载 Jupyter Notebook 时,我都不需要键入这两行代码:
plt.rcParams['figure.figsize'] = [16,8]
plt.style.use('ggplot')
Run Code Online (Sandbox Code Playgroud)
但图表仍将默认为那些大小和样式设置?
谢谢!
我已经搜索过但尚未发现如何向Seaborn Clustermap添加标题。
我试过了:
plt.title('Title',loc='center')
Run Code Online (Sandbox Code Playgroud)
但这会将标题添加到图例,而不是主Clustermap。
我也尝试过,首先创建一个轴对象并为其添加标题(这似乎适用于Heatmap),但是问题是Clustermap不会在该轴对象上绘制。它显然是在自己的对象上绘图。
谢谢你的帮助...
我正在尝试使用具有自定义每日频率的熊猫生成日期时间索引。
目前,我可以生成以下日期时间索引:
import pandas as pd
import datetime as dt
pd.date_range(start=dt.datetime(2020,8,28),end=dt.datetime(2020,9,30),freq='B')
DatetimeIndex(['2020-08-28', '2020-08-31', '2020-09-01', '2020-09-02',
'2020-09-03', '2020-09-04', '2020-09-07', '2020-09-08',
'2020-09-09', '2020-09-10', '2020-09-11', '2020-09-14',
'2020-09-15', '2020-09-16', '2020-09-17', '2020-09-18',
'2020-09-21', '2020-09-22', '2020-09-23', '2020-09-24',
'2020-09-25', '2020-09-28', '2020-09-29', '2020-09-30'],
dtype='datetime64[ns]', freq='B')
Run Code Online (Sandbox Code Playgroud)
但是,这将返回所有工作日。我想返回所有的周二、周三、周四、周五和周六。也许这可以通过某种自定义设置或某种偏移来完成?具体来说,有没有办法直接使用 date_range 功能和 freq 输入来做到这一点?如果没有,如何才能最简单地做到这一点?
谢谢!