开发者

Python function with too many arguments with default values, how to make it cleaner?

I have the following function signature, and it looks really ugly, what can I do to make it look cleaner ?

def contact(
  request, sender=settings.DEFAULT_FROM_EMAIL,
  subj_tmpl='contato/subject.txt',msg_tmpl='contato/msg.html',
  template='contato/contato.html', success_templ开发者_如何学编程ate='contato/success.html',
  success_redir='/',append_message=None,):


if i were you i think i will do it like this:

def contact(request, sender=None, append_message=None, context=None):

   if not sender:
       sender = settings.DEFAULT_FROM_EMAIL  # i hope that you can access settings here

   # The context arg is a dictionary where you can put all the others argument and 
   # you can use it like so :

   subj_tmpl = context.get('subj_tmpl', 'contato/subject.txt')
   # ....

hope this will help you.


My proposal is to drop parameters. Do you really need to be able to specify all the templates separately? Wouldn't it be sufficient to just specify the template folder, and then mandate that it has subject.txt, msg.html, etc in it?

If you just want to improve readability, reformat it to have one parameter per line:

def contact(
  request, 
  sender=settings.DEFAULT_FROM_EMAIL,
  subj_tmpl='contato/subject.txt',
  msg_tmpl='contato/msg.html',
  template='contato/contato.html', 
  success_template='contato/success.html',
  success_redir='/',
  append_message=None,):

This will allow a reader to more quickly grasp what the parameter names are.


You could rewrite it as:

def contact( request, **kargs):
    try:
        sender = kwargs.pop ('sender')
    except KeyError:
        sender=settings.DEFAULT_FROM_EMAIL

    try:
        subj_tmpl = kwargs.pop ('subj_tmpl')
    except KeyError:
        subj_tmpl='contato/subject.txt'

    # ... 
    # and so on 
    # ...


def contact(request, **kwargs):
    sender = kwargs.get('sender', settings.DEFAULT_FROM_EMAIL)
    subj_template = kwargs.get('subj_template', 'contato/subject.txt')
    ..

With that said, I think your current solution is waaay better than using **kwargs.


this does not seem so ugly to me: you have a function, you have enough parameters to modify the way the function behave, and you have sensible default values so that you don't need to specify all arguments at each function call.

there is the possibility to package the function in a class: in the class constructor, you specify all those values which are part of the parameter list, and you have a special method without arguments to execute the core feature.

something like this:

class ContactForm(object):
    def __init__( self, 
                  subj_tmpl='contato/subject.txt',
                  msg_tmpl='contato/msg.html',
                  template='contato/contato.html',  
                  success_template='contato/success.html',
                  success_redir='/',
                  append_message=None):
        self.subj_tmpl = subj_tmpl
        self.msg_tmpl = msg_tmpl
        self.template = template
        self.success_template = success_template
        self.success_redir = success_redir
        self.append_message = append_message

    def __call__( self, request, sender=settings.DEFAULT_FROM_EMAIL ):
        # do something

# use case:
contact = ContactForm()
contact( req, sndr )

(i guessed which values is site specific and which is user specific from the name of the parameters. i don't know your specific application, adapt it the way you want)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜