This has the advantage of working with any number of items:
def getfirstattr(obj, *attrs):
return next((getattr(obj, attr) for attr in attrs
if hasattr(obj, attr)), None)
This does have the very minor drawback that it does two lookups on the final value: once to check that the attribute exists, another to actually get the value. This can be avoided by using a nested generator expression:
def getfirstattr(obj, *attrs):
return next((val for val in (getattr(obj, attr, None) for attr in attrs)
if val is not None), None)
But I don't really feel it's a big deal. The generator expression is probably going to be faster than a plain old loop even with the double-lookup.