[英]Why do I need to explicitly import the font module from the tkinter module even if have imported the full module using “*”?
[英]Why do I have to “from module import” with the email module in python?
抱歉,如果沒有找到問題,我很難正確地表達這個問題。
我正在嘗試使用電子郵件模塊創建簡單的純文本電子郵件,並在滿足某些條件時將其發送。 我遇到了各種異常行為,並希望了解它。 我首先從官方示例( 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()
這很完美。 但是,如果我以不同的順序訂購東西,事情就會開始崩潰,我不明白為什么。 例如,如果我將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
失敗的原因是'module' object has no attribute 'headerregistry'
。 為什么創建EmailMessage會使其他代碼正常運行?
實際上,如果我有一個僅包含此文件的文件
import email
to_address = email.headerregistry.Address("joe", "joe@joe.com")
它失敗,並顯示相同的錯誤。
要運行該小片段,我必須這樣做
from email.headerregistry import Address
to_address = Address("joe", "joe@joe.com")
或者,這真的很奇怪,我可以讓它運行
import email
import smtplib
email.message.EmailMessage()
to_address = email.headerregistry.Address("joe", "joe@joe.com")
但是,即使刪除了這4行中的smtplib中的任何內容,如果我刪除了import smtplib
它也會再次失敗。
我敢肯定,我可以繼續嘗試所有我能想到的組合,並使其正常運行,但是我更希望了解這種行為。 這樣,我將更有信心在生產環境中運行代碼。
為什么我不能只調用import email
並用email.headderregistry.Address
聲明對象,為什么我必須from email.headerregistry import Address
顯式地導入特定功能? 為什么使用import smtplib
編譯,但是沒有它會失敗。 為什么僅在調用EmailMessage()
后才起作用?
通常,我真的很擅長尋找答案,但是我認為在這種情況下,我只是不知道要搜索什么。 對於“模塊對象沒有屬性”,有很多解決方案,但是大多數解決方案是重復的命名文件,循環導入,調用不存在的函數或檢查屬性是否存在。 他們似乎都沒有解決導入行為的工作方式。 我是否在構造代碼錯誤,還是電子郵件模塊只是對我起作用?
import email
不會自動導入email
包中的所有模塊。 這意味着,要使用email.headerregistry
,必須將其導入,可以很簡單:
import email.headerregistry
之后,您將可以使用email.headerregistry.Address
。
from email.headerregistry import Address
寫入后,您的代碼也可以工作,因為該語句在內部(等同於) import email.headerregistry
以便加載模塊並保留Address
。 同樣, smtplib
導入與email
相關的模塊,其中一些可能會導入email.headerregistry
。
總結一下:一旦任何模塊執行了email.headerregistry
導入,即使從未明確請求email.headerregistry
所有模塊 ,該子模塊也對所有導入email
模塊可見。 導入模塊可以使無關包的子模塊成為副作用的事實可能導致討厭的錯誤,即只有在其他模塊之后才導入模塊,模塊才能工作。 幸運的是,諸如pylint和Eclipse的pydev之類的現代工具很好地解決了這種陷阱。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.