Clear interface for mail class

Discussion in 'Python' started by Benedict Verheyen, Oct 14, 2009.

  1. Hi,


    I'm trying to come up with a decent interface for my email class.
    Basically, i have one email function but it has many (too many?) variables:

    send_mail(self, send_from, send_to, send_cc, subject, text, separate_emails = False, files=[], inline_files=[], server="localhost",
    charset="iso-8859-1")

    I'm thinking on how i could simplify it and make it look nicer and more easy to use.
    I can reduce the number of arguments by adding functions for the less common tasks
    like adding attachement, inline files and so on.
    Then i would end up with functions like this:

    def __init__(self):
    """
    """
    self._files=[]
    self._inline_files=[]
    ....

    def add_files(self, files=[]):
    assert type(files)==list
    self._files=files
    ....

    When sending an email, i could check if files where specified and if so, send them too.

    But it doesn't feel right to just have a bunch of small functions to set variables.
    Calling the function would change from:
    (where m is the mail class)
    m.send_mail( "from_me@work",
    "to_@work",
    [],
    "Test emailmodule ",
    MSG,
    separate_emails = True,
    files=["attached_pic.png"],
    inline_files=["inline_pic.png"],
    server="mysmtpserver")

    to:

    m.add_files(["attached_pic.png"])
    m.add_inline_files(["inline_pic.png"])
    m.smtp_server("mysmtpserver")
    m.send_mail( "from_me@work",
    "to_@work",
    [],
    "Test emailmodule "",
    MSG)

    It looks already better and i could set the smtp server as a class variable,
    but i'm not sure this will present me with the most natural interface to use.

    Or should i make 1 general function that sets vars according to a type?
    For instance: add_header("To",[list_of_recipients])

    This kind of problems seems to happen sometimes: i need to fix something quickly,
    build a script for it, and then i realise that the code i've written is not the best in
    terms of reusability and has some "not so great" functions or classes.
    Speedy development eh.

    Any ideas are welcome.

    Thanks,
    Benedict
     
    Benedict Verheyen, Oct 14, 2009
    #1
    1. Advertising

  2. Benedict Verheyen wrote:

    > Any ideas are welcome.


    easy_install turbomail

    :)
     
    Marco Mariani, Oct 14, 2009
    #2
    1. Advertising

  3. Marco Mariani wrote:
    > Benedict Verheyen wrote:
    >
    >> Any ideas are welcome.

    >
    > easy_install turbomail
    >
    > :)
    >


    Looks good but i'm still interested in how one would
    make a clean class interface for this type of problem.

    Having said that, turbomail looks quite good :)

    Thanks
     
    Benedict Verheyen, Oct 14, 2009
    #3
  4. On Oct 14, 2:39 pm, Benedict Verheyen <>
    wrote:
    > Hi,
    >
    > I'm trying to come up with a decent interface for my email class.
    > Basically, i have one email function but it has many (too many?) variables:
    >
    >     send_mail(self, send_from, send_to, send_cc, subject, text, separate_emails = False, files=[], inline_files=[], server="localhost",
    > charset="iso-8859-1")
    >
    > I'm thinking on how i could simplify it and make it look nicer and more easy to use.
    > I can reduce the number of arguments by adding functions for the less common tasks
    > like adding attachement, inline files and so on.
    > Then i would end up with functions like this:
    >
    > def __init__(self):
    >     """
    >     """
    >     self._files=[]
    >     self._inline_files=[]
    > ...
    >
    > def add_files(self, files=[]):
    >     assert type(files)==list
    >     self._files=files
    > ...
    >
    > When sending an email, i could check if files where specified and if so, send them too.
    >
    > But it doesn't feel right to just have a bunch of small functions to set variables.
    > Calling the function would change from:
    >  (where m is the mail class)
    >  m.send_mail( "from_me@work",
    >               "to_@work",
    >               [],
    >               "Test emailmodule ",
    >               MSG,
    >               separate_emails = True,
    >               files=["attached_pic.png"],
    >               inline_files=["inline_pic.png"],
    >               server="mysmtpserver")
    >
    > to:
    >
    > m.add_files(["attached_pic.png"])
    > m.add_inline_files(["inline_pic.png"])
    > m.smtp_server("mysmtpserver")
    > m.send_mail( "from_me@work",
    >              "to_@work",
    >              [],
    >              "Test emailmodule "",
    >              MSG)
    >
    > It looks already better and i could set the smtp server as a class variable,
    > but i'm not sure this will present me with the most natural interface to use.
    >
    > Or should i make 1 general function that sets vars according to a type?
    > For instance: add_header("To",[list_of_recipients])
    >
    > This kind of problems seems to happen sometimes: i need to fix something quickly,
    > build a script for it, and then i realise that the code i've written is not the best in
    > terms of reusability and has some "not so great" functions or classes.
    > Speedy development eh.
    >
    > Any ideas are welcome.
    >
    > Thanks,
    > Benedict


    I would add a server class, maybe subclassing something in standard
    library, and add to it the 'send' method, so that sending a mail would
    be
    something like:

    myserver = MyMailServer("mysmtpserver", "localhost", ) # this only
    needs to be done once, not for each mail

    m = MyMail( subject, text, separate_emails = False, files=[],
    inline_files=[] ) # mail creation

    myserver.send( m, from= "from_me@work", # mail sending
    to = "to_@work",
    cc_to= None )

    Note that I put sender and destination senders in the send method, not
    as attributes of the mail object. It makes more sense to me, and yopu
    can reuse
    the same object if you want to send the same mail to many addresses
    ( and/or via different servers ).

    IN general, un case like yours I use a lot default parameters, as you
    did already. Having separate methods to setting specific part of an
    object only makes
    sens (to me) if you need first to create an object and later change
    some of the attributes. Also, if you are just going to change the
    attributes, you do not
    need a method: just use the object.attribute = value syntax. If you
    are going to need later to do more complex thing, you can always
    transform your
    attribute in a property.
     
    Francesco Bochicchio, Oct 14, 2009
    #4
  5. Francesco Bochicchio wrote:
    <snip>
    >
    > I would add a server class, maybe subclassing something in standard
    > library, and add to it the 'send' method, so that sending a mail would
    > be
    > something like:
    >
    > myserver = MyMailServer("mysmtpserver", "localhost", ) # this only
    > needs to be done once, not for each mail
    >
    > m = MyMail( subject, text, separate_emails = False, files=[],
    > inline_files=[] ) # mail creation
    >
    > myserver.send( m, from= "from_me@work", # mail sending
    > to = "to_@work",
    > cc_to= None )
    >
    > Note that I put sender and destination senders in the send method, not
    > as attributes of the mail object. It makes more sense to me, and yopu
    > can reuse
    > the same object if you want to send the same mail to many addresses
    > ( and/or via different servers ).
    >
    > IN general, un case like yours I use a lot default parameters, as you
    > did already. Having separate methods to setting specific part of an
    > object only makes
    > sens (to me) if you need first to create an object and later change
    > some of the attributes. Also, if you are just going to change the
    > attributes, you do not
    > need a method: just use the object.attribute = value syntax. If you
    > are going to need later to do more complex thing, you can always
    > transform your
    > attribute in a property.



    Thanks for the input guys

    Cheers,
    Benedict
     
    Benedict Verheyen, Oct 15, 2009
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Wildepiet
    Replies:
    0
    Views:
    1,870
    Wildepiet
    Jun 14, 2004
  2. E11
    Replies:
    1
    Views:
    4,844
    Thomas Weidenfeller
    Oct 12, 2005
  3. cyberco
    Replies:
    8
    Views:
    501
    cyberco
    Feb 25, 2006
  4. David

    Response.Clear() doesn't clear

    David, Jan 31, 2008, in forum: ASP .Net
    Replies:
    2
    Views:
    1,070
    Mark Fitzpatrick
    Jan 31, 2008
  5. InvalidLastName

    Unrecognized element 'add' after <clear></clear>

    InvalidLastName, Feb 26, 2007, in forum: ASP .Net Web Services
    Replies:
    3
    Views:
    1,009
    Steven Cheng[MSFT]
    Mar 6, 2007
Loading...

Share This Page