使用条件语句 (IF/ELIF/ELSE) 的代码更简洁、更短
Cleaner, shorter code using conditionals (IF/ELIF/ELSE)
目标: 使用 IF/ELIF/ELSE 条件句减少 (Python) retrieve_method 的冗长。
对象的结构Table和方法:这个特定的retrieve_method根据构成用户table的元素调用用户对象在数据库中(例如 username
、firstname
、lastname
、email
等)
截至目前,我的代码可以正常工作,但它可以使用更干净、更简洁的代码。我不确定我应该使用 keywords
还是 *args
。我仍在学习 Python,因此非常感谢任何有用的建议。 (你会注意到我现在正在使用抽象词 something_unique
来比较输入与 table 中找到的元素。如果两者匹配,方法 returns 匹配项。)
我该如何改进?最好的方法是什么?优点?缺点?
软件:Python2.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')
一种方法是使用关键字参数:
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
你可以在python中使用字典来获取switch语句的行为,它会比if/elif/else模式更有效。在这里用代码描述得很好:
http://code.activestate.com/recipes/181064/
来自 link 的示例:
#! /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)
没有关于何时调用它以及在什么上下文中调用的更多详细信息,我只能提出一些建议来清理它。
建议主要是使用局部变量来存储你经常调用的东西,即self.session.query(User),以及以小写开头的标识符。
我想明确一点,特别是在 "identifier = func.lower(...)" 时,您最终会遇到这样一种情况,如果这最终成为一个 ID,您就做了一些不必要的工作。
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(...) 本身,因为您仍然需要为别处的字典对象!它当然可以帮助你分解,如果你在其他地方使用这些功能,或者有一个巨大的 elif 级联系列,那绝对是值得的。否则我会把它作为一个功能。
目标: 使用 IF/ELIF/ELSE 条件句减少 (Python) retrieve_method 的冗长。
对象的结构Table和方法:这个特定的retrieve_method根据构成用户table的元素调用用户对象在数据库中(例如 username
、firstname
、lastname
、email
等)
截至目前,我的代码可以正常工作,但它可以使用更干净、更简洁的代码。我不确定我应该使用 keywords
还是 *args
。我仍在学习 Python,因此非常感谢任何有用的建议。 (你会注意到我现在正在使用抽象词 something_unique
来比较输入与 table 中找到的元素。如果两者匹配,方法 returns 匹配项。)
我该如何改进?最好的方法是什么?优点?缺点?
软件:Python2.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')
一种方法是使用关键字参数:
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
你可以在python中使用字典来获取switch语句的行为,它会比if/elif/else模式更有效。在这里用代码描述得很好:
http://code.activestate.com/recipes/181064/
来自 link 的示例:
#! /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)
没有关于何时调用它以及在什么上下文中调用的更多详细信息,我只能提出一些建议来清理它。
建议主要是使用局部变量来存储你经常调用的东西,即self.session.query(User),以及以小写开头的标识符。
我想明确一点,特别是在 "identifier = func.lower(...)" 时,您最终会遇到这样一种情况,如果这最终成为一个 ID,您就做了一些不必要的工作。
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(...) 本身,因为您仍然需要为别处的字典对象!它当然可以帮助你分解,如果你在其他地方使用这些功能,或者有一个巨大的 elif 级联系列,那绝对是值得的。否则我会把它作为一个功能。