更清洁,更短的代码使用条件(IF / ELIF / ELSE)

时间:2016-01-26 15:53:00

标签: python sqlalchemy crud

目标:使用IF / ELIF / ELSE条件减少(Python)retrieve_method的冗长。

对象表和方法的结构:这个特定的retrieve_method根据构成数据库中User表的元素调用用户对象(例如usernamefirstnamelastnameemail等)

截至目前,我的代码正在运行,但它可以使用一些更干净,更整洁的代码。我不确定是否应该使用keywords*args。我还在学习Python,所以任何提供信息的建议都会非常感激。 (你会注意到我现在使用一个抽象词something_unique来比较输入到表中找到的元素。如果两者匹配,则该方法返回匹配的项目。)

我该如何改进?什么是最好的方式?优点?缺点

软件:Python 2.7.9,SQLAlchemy 1.0.9

代码:

def retrieve_user(self, something_unique):
    if isinstance(something_unique, int):
        print 'retrieve_user_id: ', something_unique # added
        return self.session.query(User).\
            filter(User.id == something_unique).one()
    elif isinstance(something_unique, basestring):
        print 'retrieve_user: ', something_unique # added
        return self.session.query(User).\
            filter(func.lower(User.username) == func.lower(something_unique)).first() 
    elif isinstance(something_unique, basestring):
        print 'retrieve_user email', something_unique
        return self.session.query(User).\
            filter(func.lower(User.email) == func.lower(something_unique)).first()
    elif isinstance(something_unique, User):
        return something_unique
    else:
        raise ValueError('Value being passed is an object')

3 个答案:

答案 0 :(得分:1)

一种方法是使用关键字参数:

def retrieve_user(self, id=None, name=None, email=None):
    if id:
        return self.session.query(User).\
            filter(User.id == id).one()
    if name:
        return self.session.query(User).\
            filter(func.lower(User.username) == func.lower(name)).first()
etc

答案 1 :(得分:1)

如果没有关于何时调用此内容以及在何种上下文中的更多详细信息,我只能提出一些建议来清理它。

建议主要是使用局部变量来存储你经常调用的东西,即self.session.query(User),以及小写标识符以开始。

我想要明确,特别是在做" identifier = func.lower(...)"时,你最终会遇到这样的情况,如果这最终成为一个ID,你就是# 39;做了一些不必要的工作。

def retrieve_user(self, something_unique):
    query_service = self.session.query(User)
    identifier = func.lower(something_unique)
    if isinstance(something_unique, int):
        print 'retrieve_user_id: ', something_unique # added
        return query_service.filter(User.id == something_unique).one()
    elif isinstance(something_unique, basestring):
        print 'retrieve_user: ', something_unique # added
        return query_service.filter(func.lower(User.username) == identifier).first() 
    elif isinstance(something_unique, _basestring):
        print 'retrieve_user email', something_unique
        return query_service.filter(func.lower(User.email) == identifier).first()
    elif isinstance(something_unique, User):
        return something_unique
    else:
        raise ValueError('Value being passed is an object')

老实说,这不是一种不洁净的方法。如果你反复这样做,你可以考虑重构字典。

为此,您可以将类型存储为键,将函数存储为值。然后你可以做......

def retrieve_user(self, something_unique, func_dict):
    for key in func_dict:
        if isinstance(something_unique, key): return func_dict[key](something_unique)
    raise ValueError("Value being passed is an object")

请注意,最后一个建议是语义的 - 除了retrieve_user(...)本身之外,它并没有真正为您节省大量代码,因为您仍需要为其他地方的字典对象定义这些函数!它当然可以帮助你分解,如果你在其他地方使用这些功能,或者有一个巨大的级联系列精灵,绝对值得。否则我会把它作为一个功能。

答案 2 :(得分:0)

您可以在python中使用字典来获取switch语句的行为,并且它比if / elif / else模式更有效。这里有代码的良好描述:

http://code.activestate.com/recipes/181064/

链接示例:

#! /usr/local/bin/python

# /////////////////////////////////////////////////////////////////////////
# /**
# * Title: rochambeau.py
# *
# * Description: Rock, Scissors, Paper Game. 
# *              Shows a clean way of implementing a 'switch'
# *              statement in Python via a dictionary container. 
# *              The dictionary is made up of known 'named states' that
# *              are tested in sequence for their current 'state'.
# *
# * Copyright: Copyright (c) 2003
# *            This file is distributed as EXAMPLE SOURCE CODE ONLY!
# *            The following code is considered 'Freeware' and can be 
# *            freely copied/reused/distributed as needed. 
# *
# * Company: None
# * @author: Alan Haffner
# * @version 1.0
# */
# 
# /////////////////////////////////////////////////////////////////////////
# Date: 02/16/03


import os, sys
import string, random
import types

def cli():

   c = '?'
   while c not in 'rps':

      try:
         print
         # tailing index '[0]' picks only first char from input
         c = raw_input('\tPlease enter (r)ock, (p)aper or (s)cissors to play... ')[0]
      except IndexError:
         # bad input, so like get another...
         pass

      c = c.lower()

      #   x, q...   --> quit
      if c in ('x', 'q' ):
         raise 'USER_QUIT_ERROR'

   return c

if __name__=='__main__':

   errorCode = 0

   stateList = ['r', 'p', 's']

   validStates = { 'User Wins'      : (('p','r'), ('r','s'), ('s','p')),
                   'No One Wins'    : (('p','p'), ('r','r'), ('s','s')),
                   'Computer Wins'  : (('r','p'), ('s','r'), ('p','s')),
   }

   try:
      while 1:
         testTuple     = (None, None)
         userInput     =        None
         computerInput =       '?'

         userInput     = cli()
         computerInput = ( stateList[random.randint(0,2)] )

         testTuple = (userInput, computerInput)

         for select in validStates:
            if testTuple in validStates[select]:
               print
               print "You chose:         ", userInput
               print "The computer chose:", computerInput
               print " ****", select, " ****" 
               print

   # Note: By convention, all local exception 'constants' end 
   # in '_ERROR' regaurdless of their intended use. 
   except KeyboardInterrupt:
      print '\n' * 3
      print '[interrupted by user]'
      print '\n' * 3
   except 'USER_QUIT_ERROR':
      print '\n' * 3
      print '[interrupted by user]'
      print '\n' * 3
   except:
      # unexpected error
      print '\n' * 3
      traceback.print_exc()
      print '\n' * 3

      errorCode = 2

   sys.exit(errorCode)