Sta*_*kes 1 python email import attributes smtplib
对不起,如果问题没有发现,我很难正确地表达这个问题.
我正在尝试使用电子邮件模块创建一个简单的纯文本电子邮件,并在满足某些条件时发送它.我正在遇到各种异常行为,并希望了解它.我开始从官方示例(https://docs.python.org/3.4/library/email-examples.html)中提取一个简单的测试,它工作正常.当我开始尝试在我的项目中实现这一点时,我开始得到各种各样的"'module' object has no attribute 'something'".我可以运行这样的东西,它工作正常
import email
import smtplib
# Create message object
msg = email.message.EmailMessage()
# Create the from and to Addresses
from_address = email.headerregistry.Address("Stack of Pancakes", "pancakes@gmail.com")
to_address = email.headerregistry.Address("Joe", "pythontest@mailinator.com")
# Create email headers
msg['Subject'] = "subject of email"
msg['From'] = from_address
msg['To'] = to_address
#
email_content = "This is a plain text email"
msg.set_content(email_content)
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login("pancakes@gmail.com", "password")
server.send_message(msg)
server.quit()
Run Code Online (Sandbox Code Playgroud)
这非常有效.但是,如果我以不同的方式订购东西,事情就会开始破碎,我不明白为什 例如,如果我将from_address和to_address上面的行放在EmailMessage被调用的地方,就像这样
import email
import smtplib
# Create the from and to Addresses
from_address = email.headerregistry.Address("Stack of Pancakes", "pancakes@gmail.com")
to_address = email.headerregistry.Address("Joe", "pythontest@mailinator.com")
# Create message object
msg = email.message.EmailMessage()
... other code
Run Code Online (Sandbox Code Playgroud)
它失败了'module' object has no attribute 'headerregistry'.为什么EmailMessage创建允许其他代码正常运行?
事实上,如果我有一个只包含此文件的文件
import email
to_address = email.headerregistry.Address("joe", "joe@joe.com")
Run Code Online (Sandbox Code Playgroud)
它失败并出现同样的错误.
为了让这个小片段运行我必须这样做
from email.headerregistry import Address
to_address = Address("joe", "joe@joe.com")
Run Code Online (Sandbox Code Playgroud)
或者,这真的很奇怪,我可以让它运行
import email
import smtplib
email.message.EmailMessage()
to_address = email.headerregistry.Address("joe", "joe@joe.com")
Run Code Online (Sandbox Code Playgroud)
但是如果我删除import smtplib它会再次开始失败,即使我没有在这4行中使用smtplib中的任何内容.
我相当肯定我可以继续尝试我能想到的每一个组合并让它正常工作,但我更愿意理解这种行为.这样我就会更有信心在生产环境中运行代码.
为什么我不能只调用import email和声明我的对象email.headderregistry.Address,为什么我必须显式导入该特定函数from email.headerregistry import Address?为什么它会编译import smtplib但没有它就失败了.为什么它只在EmailMessage()被调用后才能工作?
通常我很擅长寻找答案,但我认为在这种情况下我只是不知道要搜索什么."模块对象没有属性"有很多解决方案,但大多数都是重复的命名文件,循环导入,调用不存在的函数或检查属性是否存在.他们似乎都没有解决导入行为如何运作的问题.我构建错误的代码还是电子邮件模块只是对我有所影响?
import email不会自动导入email包内的所有模块.这意味着,为了使用email.headerregistry,您必须导入它,这可以很简单:
import email.headerregistry
Run Code Online (Sandbox Code Playgroud)
之后你就可以使用了email.headerregistry.Address.
您的代码也可以在写入后工作,from email.headerregistry import Address因为该语句在内部执行(等效于)import email.headerregistry以加载模块并获取Address.同样,smtplib进口email相关的模块,其中一些可能是进口email.headerregistry.
总结一下:一旦任何模块执行导入email.headerregistry,该子模块对于导入的所有模块都是可见的email,即使它们从未明确请求过email.headerregistry.导入模块的事实可以使不相关的包的子模块作为副作用可以导致令人讨厌的错误,其中模块仅在某些其他模块之后导入时才起作用.幸运的是,像pylint和Eclipse的pydev这样的现代工具很好地解决了这种陷阱.
| 归档时间: |
|
| 查看次数: |
259 次 |
| 最近记录: |