如何使用模块提取当前的python文件名?

问题描述

文件运行完毕后,我正在为一个简单的电子邮件任务构建一个模块。它被称为 emaildone.py:

import sys
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
import datetime
global fileName
fileName=os.path.basename(sys.argv[0][:-3])

def whendone(to,fro=None,fname=fileName):
    if fro is None:
        fro = to
    #Email me confirmation of run    
    fname=fileName
    sendTo=to
    sendFrom=fro
    date=str(datetime.date.today())
      
    # Create the root message and fill in the from,to,and subject headers
    msgRoot = MIMEMultipart('mixed')
    msgRoot['Subject'] = fname
    msgRoot['From'] = sendFrom
    msgRoot['To'] = sendTo
    msgRoot.preamble = 'This is a multi-part message in MIME format.'
    #msgText = MIMEText('no alternative text version')
    #msgalternative.attach(msgText)
    
    # Encapsulate the plain and HTML versions of the message body in an
    msgText = """
    The """+fname+""" job has ran successfully for """+date+"""
    """
    
    part1 = MIMEText(msgText,'plain')
    msgRoot.attach(part1)
    
    # Send the email (this example assumes SMTP authentication is required)
    import smtplib
    smtp = smtplib.SMTP()
    smtp.connect('localhost')
    #smtp.login('exampleuser','examplepass')
    smtp.sendmail(sendFrom,sendTo,msgRoot.as_string())
    smtp.quit()
    print('Done!')

然后在另一个名为 test.ipynb 的笔记本中,我像这样导入它:

import sys
sys.path.append('/my/path/') 
import datetime
import emaildone as email

email.whendone('first.last@email.com')

问题是 fname 总是作为 __main__ 而不是文件名返回。 fname 应该是“测试”。以便电子邮件将“测试”作为主题行,消息将显示“测试作业已成功运行(日期)”

如何让 fname 成为当前文件名 vs __main__?当我第一次开始构建它时 sys.argv[0] 正在工作,但不知何故它现在显示__main__

解决方法

您的代码有两个问题。

  1. 您的代码在模块导入时执行,而不是在调用时执行。

尝试将以下内容添加到 emaildone.py 的末尾:

if __name__ == '__main__':
   pass

当解释器运行一个模块时,如果正在运行的模块是主程序,则 name 变量被设置为 ma​​in

当使用if __name__ == '__main__':时,模块中的代码只有通过调用直接运行文件而不是导入时才会执行。在您的情况下,导入模块时,代码正在执行,因为它没有 if __name__ == '__main__' 检查。

但如果代码从另一个模块导入一个模块(并且不直接运行代码),那么 __name__ 变量将设置为该模块的名称。

  1. 您想获取文件名“test”,但您正在 emaildone.py 中设置全局变量 fileName。

要获得“test”,您需要像这样在 test.pynb 中设置变量:

file_name = os.path.basename(__file__).split('.')[0]

这将为您提供不带扩展名的文件名。然后你应该像这样将这个变量作为 'fname' arg 传递给 whendone:

email.whendone('first.last@email.com',fname=file_name)