2014-10-11 84 views
1

我是Python新手。我正在嘗試製作可發送電子郵件的電子郵件腳本。首先,我創建了一個沒有任何類的Python腳本,只是用來確保腳本按預期運行。我得到了預期的結果。我正在嘗試使用類重寫腳本,以便學習。但是我收到了錯誤,我不明白。我不明白問題實際上在哪裏。AttributeError:'str'對象沒有'policy'屬性

下面是代碼以及錯誤

import smtplib 
import os 
import sys 
import mimetypes #for guess mime types of attachment 

from email import encoders 
from email.mime.multipart import MIMEMultipart 
from email.mime.text import MIMEText 
from email.mime.audio import MIMEAudio 
from email.mime.base import MIMEBase 
from email.mime.image import MIMEImage 

class Email(object): 
    message = None 
    subject = None 
    from_address = None 
    to_address = None 
    body = None 
    email_server = None 
    attachment = None 

    def __init__(self,from_address,to_address,subject,body,attachment,email_server): 
    self.message = MIMEMultipart() 
    self.message['subject'] = subject 
    self.message['From'] = from_address 
    self.message['TO'] = to_address 
    self.body = MIMEText(body, 'plain') 
    self.message.attach(body) 
    self.email_server = email_server 

    if attachment is not None: 
     self.attachment = attachment 
     self.attach_attachment() 

    def get_message(self): 
    return self.message 

    def send_message(self,auth): 
    username, password = auth.get_user_auth_details() 

    server = smtplib.SMTP(self.email_server) 
    server.starttls() #For Encryption 
    server.login(username, password) 
    server.send_message(self.message) 
    server.quit() 

    def attach_attachment(self): 
    self.messaege = self.attachment.set_attachment_type(self.message) 



class Security(object): 
    username = "" 
    password = "" 

    def __init__(self,username, password): 
    self.username = username 
    self.password = password 


    def get_user_auth_details(self): 
    return self.username, self.password 

class Attachment(object): 
    attachment_path = '' 

    def __init__(self,attachment_path): 
    self.attachment_path = attachment_path 

    def is_directory(self): 
    return os.path.isdir(self.attachment_path) 

    def is_file(self): 
    return os.path.isfile(self.attachment_path) 

    def guess_and_get_attachment_type(self, filenamepath): 
    ctype, encoding = mimetypes.guess_type(filenamepath) 

    if ctype is None or encoding is not None: 
     # No guess could be made, or the file is encoded (compressed), so 
     # use a generic bag-of-bits type. 
     ctype = "application/octet-stream" 

    maintype , subtype = ctype.split('/' , 1) 

    if maintype == 'text': 
     fp = open(filenamepath) 
     attachment = MIMEText(fp.read() , subtype) 
     fp.close() 
    elif maintype == 'image': 
     fp = open(filenamepath , 'rb') 
     attachment = MIMEImage(fp.read() , subtype) 
     fp.close() 
    elif maintype == 'audio': 
     fp = open(filenamepath , 'rb') 
     attachment = MIMEAudio(fp.read() , subtype) 
     fp.close() 
    else: 
     fp = open(filenamepath , 'rb') 
     attachment = MIMEBase(maintype , subtype) 
     attachment.set_payload(fp.read()) #Actual message 
     fp.close() 
     encoders.encode_base64(attachment) # Encode the payload using Base64 

    return attachment 

    def set_attachment_type(self,message): 
    if(self.is_directory()): 
     for filename in os.listdir(self.attachment_path): 
     filenamepath = os.path.join(self.attachment_path , filename) 
     attachment = self.guess_and_get_attachment_type(filenamepath) 
     # Set the filename parameter 
     attachment.add_header('Content-Disposition', 'attachment', filename = filenamepath) 
     message.attach(attachment) 

    elif(self.is_file()): 
     attachment = self.guess_and_get_attachment_type(self.attachment_path) 
     # Set the filename parameter 
     attachment.add_header('Content-Disposition', 'attachment', filename = self.attachment_path) 
     message.attach(attachment) 
    else: 
     print("Unable to open file or directory") 

    return message 



def main(): 
    #Constants 
    GMAIL_SERVER = "smtp.gmail.com:587" 
    FROM_ADDRESS = "[email protected]" 
    TO_ADDRESS = "[email protected]" 

    auth = Security("[email protected]" , "MySuperSecretPassword") 
    attachment = Attachment("/path/to/attachment/file/or/directory") 
    email = Email(FROM_ADDRESS ,TO_ADDRESS, "Hi from class Python" , "OOPs Python at Work!!" ,attachment,GMAIL_SERVER) 

    email.send_message(auth) 
if __name__ == '__main__': 
    main() 

enter image description here

+1

它幾乎與錯誤狀態完全一樣。在這裏粘貼generator.py。 – brian 2014-10-11 04:26:36

+0

字符串對象沒有名爲policy的屬性。 – csmckelvey 2014-10-11 04:28:32

+1

這就是爲什麼我不喜歡鴨子打字+ EAFP。我更喜歡在公共API的入口處放置'assert isinstance(msg,MIMEBase)'或'hasattr(msg,'policy')',而不是象這個問題那樣向用戶展示回溯。早期失敗比調試這樣的追溯更好。 – warvariuc 2014-10-11 04:57:55

回答

3

的我改變

self.message.attach(body) #In the class email constructor 

self.message.attach(self.body) #In the class email constructor 

截圖和它的工作。

我將字符串類型附加到消息而不是MIMEText

+0

真 - 有相同的錯誤。只需使用'msg.attach(MIMEText(str_text))' – gies0r 2016-12-21 15:26:42