Python函数有太多参数和默认值,如何让它更干净?

时间:2010-11-01 08:39:15

标签: python django django-views

我有以下功能签名,看起来很丑,我该怎么做才能让它看起来更干净?

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,):

5 个答案:

答案 0 :(得分:4)

如果我是你,我想我会这样做:

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')
   # ....

希望这会对你有所帮助。

答案 1 :(得分:3)

我的建议是删除参数。您真的需要能够单独指定所有模板吗?仅仅指定模板文件夹,然后强制它有subject.txt,msg.html等就不够了吗?

如果您只是想提高可读性,请将其重新格式化为每行一个参数:

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,):

这将使读者能够更快地掌握参数名称。

答案 2 :(得分:0)

您可以将其重写为:

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 
    # ...

答案 3 :(得分:0)

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

话虽如此,我认为您当前的解决方案比使用**kwargs更好。

答案 4 :(得分:0)

这对我来说似乎并不那么难看:你有一个函数,你有足够的参数来修改函数的行为方式,并且你有合理的默认值,所以你不需要在每个函数调用时指定所有参数

有可能将函数打包在一个类中:在类构造函数中,指定所有那些属于参数列表的值,并且您有一个不带参数的特殊方法来执行核心功能。

类似的东西:

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 )

(我猜测哪些值是特定于站点的,哪些是用户特定的参数名称。我不知道您的具体应用,按照您想要的方式进行调整)