This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author rhettinger
Recipients gvanrossum, r.david.murray, rhettinger, tebeka
Date 2018-05-05.21:35:58
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1525556158.16.0.682650639539.issue14384@psf.upfronthosting.co.za>
In-reply-to
Content
Here are a few more thoughts and a concrete example for clarity.

Itemgetter/Attrgetter were designed to make multiple lookups (possibly multi-level) and to return a tuple that need not be homogenous.  A single default value likely doesn't make sense in any of those contexts. 

Consider:

    attrgetter('programmer.lang', 'team.dept')

Various behaviors you might want:

    (o.programmer.lang if hasattr(o, 'programmer') else o.avg_joe.lang, o.team.dept)

    (o.programmer.lang if hasattr(o.programmer) else 'python', o.team.dept)

    (o.programmer.long, o.team.dept if hasattr(o.team, 'dept') else 'accounting')

    try:
        return (o.programmer.lang, o.team.dept)
    except AttributeError:
        return ('python', 'accounting')

Other than the OP's example with a universal default value of None (which would like require more tests downstream), I can't think of any meaningful default value that would apply to both programmer.lang and team.dept.

If this proposal is to go forward, its needs a more informative use case than the toy example provided on python-ideas:
                
    p1 = {'x': 43; 'y': 55} 
    x, y, z = itemgetter('x', 'y', 'z', default=0)(values) 
    print(x, y, z) 
    43, 55, 0 

And if it does go forward, I would suggest that the semantics of default be an entire result tuple rather than a scalar applied on an attribute by attribute basis:

    attrgetter('programmer.lang', 'team.dept', default=('python', 'accounting'))
    attrgetter('temperature', 'humidity', 'altitude', default=('22°C', '50%', "0 meters MSL"))
    attrgetter('foo', default=None)

That would still meet the OP's use case, but would be more broadly applicable and not make the assumption that every field has the same default value.  

Even with that improvement, users would still likely be better-off writing a function that explicitly says what they want to do.  For example, the OP's use case can already be written like this:

    get = lambda obj:  getattr(obj, 'foo', None)
    return get(args) or get(config) or get(env)

That is easy and unambiguous.  Writing a separate function allows all of the above cases to be written cleanly.  There isn't any need to trick-out itemgetter() for this.
History
Date User Action Args
2018-05-05 21:35:58rhettingersetrecipients: + rhettinger, gvanrossum, tebeka, r.david.murray
2018-05-05 21:35:58rhettingersetmessageid: <1525556158.16.0.682650639539.issue14384@psf.upfronthosting.co.za>
2018-05-05 21:35:58rhettingerlinkissue14384 messages
2018-05-05 21:35:58rhettingercreate