2014-10-11 2 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

+0

Объекты String не имеют атрибута с именем policy. – csmckelvey

+1

Вот почему я не люблю утиную печатание + EAFP. Я предпочитаю ставить 'assert isinstance (msg, MIMEBase)' или 'hasattr (msg, 'policy')' при входе в открытый API вместо представления пользовательских трассировок, как в этом вопросе. Неудачная ранняя работа лучше, чем отладка трассировок, подобных этой. – warvariuc

ответ

3

Я изменил

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

в

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

, и она работала.

Я прикреплял тип строки к сообщению вместо MIMEText

+0

True - Произошла такая же ошибка. Просто используйте 'msg.attach (MIMEText (str_text))' – gies0r

Смежные вопросы