A veces en mi código tengo una función que puede tomar un argumento de una de dos maneras. Algo así como:¿Patrón elegante para args de palabra clave mutuamente excluyentes?
def func(objname=None, objtype=None):
if objname is not None and objtype is not None:
raise ValueError("only 1 of the ways at a time")
if objname is not None:
obj = getObjByName(objname)
elif objtype is not None:
obj = getObjByType(objtype)
else:
raise ValueError("not given any of the ways")
doStuffWithObj(obj)
¿Hay alguna forma más elegante de hacer esto? ¿Qué pasa si el arg puede venir en una de tres maneras? Si los tipos son distintos, podría hacer:
def func(objnameOrType):
if type(objnameOrType) is str:
getObjByName(objnameOrType)
elif type(objnameOrType) is type:
getObjByType(objnameOrType)
else:
raise ValueError("unk arg type: %s" % type(objnameOrType))
Pero, ¿y si no lo son? Esta alternativa parece tonta:
def func(objnameOrType, isName=True):
if isName:
getObjByName(objnameOrType)
else:
getObjByType(objnameOrType)
causa, entonces usted tiene que llamar así func(mytype, isName=False)
lo cual es raro.
¿Por qué no tendría simplemente dos funciones separadas, una aceptando un nombre y la otra aceptando un tipo? Este enfoque parece que solo confundiría a los consumidores de la API. –
O, si realmente quieres tener una sola función que lo haga todo, ¿por qué no simplemente aceptas un solo argumento y luego descubres cuál es? Si el argumento es un tipo, busque el objeto por tipo, de lo contrario, búsquelo por su nombre. O simplemente pruebe uno y luego el otro y vea cuál funciona (no puedo imaginar un caso en el que ambos recuperen algo). – kindall
@Mark: si el func es un constructor que no funcionará – Claudiu