The *locals(...) thing looks pretty nice and would clearly take away a lot of the pain I was talking about! Thanks
On 26 Jun 2013, at 16:46, Joshua Landau <joshua.landau.ws@gmail.com> wrote:
On 26 June 2013 09:04, Ethan Furman <ethan@stoneleaf.us> wrote:
On 06/26/2013 12:48 AM, Greg Ewing wrote:
Ron Adam wrote:
And I don't like the '=' with nothing on the right.
Expanding on the suggestion someone made of having a single marker of some kind in the argument list, I came up with this:
def __init__(self, text, font = system_font, style = 'plain'): default_size = calc_button_size(text, font, style) Widget.__init__(self, size = default_size, pass font, style)
I don't care for it.
A word doesn't stand out like a character does, plus this usage of pass is completely different from its normal usage.
We're already used to interpreting '*' as a coin with two sides, let's stick with it:
def apply_map(map, target, *, frobble): # '*' means frobble is keyword only ...
and later:
frobble = some_funny_stuff_here() . . . apply_map(map=kansas, target=toto, *, frobble) # '*' means frobble maps to keyword frobble
Whilst Greg Ewing has made me also much more sympathetic to this view, I feel that:
1) This is nearly unreadable - it does not say what it does in the slightest
2) It's added syntax - that's a high barrier. I'm not convinced it's worth it yet.
3) It still feels like hackery; I might prefer something explicitly hackery like this:
apply_map(map=kansas, target=toto, **locals("frobble"))
where locals is:
def locals(*args): if args: return {arg:original_locals()[arg] for arg in args} else: return original_locals()
For Greg's he'd use:
def __init__(self, text="Hello", font=system_font, **kwds): default_size = calc_default_size(text, font) Widget.__init__(self, size=default_size, **locals("font"), **kwds)
or even
def __init__(self, text = "Hello", font = system_font, **kwds): default_size = calc_default_size(text, font) Widget.__init__(self, **locals("size", "font"), **kwds)
under the asumption that http://bugs.python.org/issue2292 does get implemented first.
For reference, he is using (respaced for consistency):
def __init__(self, text="Hello", font=system_font, **kwds): default_size = calc_default_size(text, font) Widget.__init__(self, size=default_size, font=font, **kwds)
Note that this is only a way to suggest that *there might be another way*; maybe something involving objects.
3 cont.) The reason I think it feels like hackery is simply that I don't feel like Python is ever "reference by name"; objects don't know what they are called (some know what they *were* named; but they have no guarantee it's true) it feels *very wrong* to give "foobar" to function and have that function somehow extract the name! I know it's not doing that, but it's ever-so-close.
However; maybe:
class AttrDict(dict): def __init__(self, mapping, **defaults): super().__init__(defaults, **mapping) self.__dict__ = self
def __init__(self, **kwds): kwds = AttrDict(kwds, text="Hello", font=system_font)
kwds.size = calc_default_size(kwds.text, kwds,font)
Widget.__init__(self, **kwds)
and a decorator could even make this:
@dynamic_kwds(text="Hello", font=system_font) def __init__(self, kwds): kwds.size = calc_default_size(kwds.text, kwds,font) Widget.__init__(self, **kwds)
which would have the same run-time effect as the original (the second keeps re-evaluating the signature).
Again; I mention these only to show people not to have a restricted idea on what the solution looks like - don't just try and fix the symptoms of the problem. _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas