En Tue, 20 Oct 2009 18:42:07 -0300, Alf P. Steinbach <al...@start.no> escribió:

I'm just learning Python from scratch, on my own. Apologies if this question is too newbie... Or perhaps answered in some FAQ (where?).

Welcome! I hope you'll enjoy the language. And no, it's not a trivial question.

import Tkinter
canvas = Tkinter.Canvas( window, bg = "white" )
bbox = 2, 2, 347, 197
canvas.create_oval( bbox, fill = "PeachPuff" )
[...]

It worked nicely, and I thought this code was fairly perfect until I started studying the language reference.

It seems that formally correct code should apply the scatter operator to the tuple, like this:

canvas.create_oval( *bbox, fill = "PeachPuff" )

And this /also/ works nicely!

I think it's this latter that is correct, and that the former just worked by accident, due to e.g. the way that some C function parses arguments or such? But I'm unable to figure it out, so, what's correct (both? one?), and assuming it's the latter that's correct, would the first version still work in practice regardless of Python / Tkinter implementation?

You can look for yourself, the high-level functions in Tkinter are written in Python (there is a compiled C module too, _tkinter). Look into Lib\lib-tk\Tkinter.py, Canvas.create_oval.

Warning: Tkinter is a very old library, and its code is not "pythonic" enough by today's standards. In particular, Tkinter was originally written _before_ the *args, **kw syntax was available. Several functions took a _tuple_ of parameters and an explicit _dictionary_ for optional parameters; support for variable number of arguments was added later. The code is written in such a way to collect all positional arguments into a tuple (flattening any inner list or tuple); if the last item in that tuple is a dictionary, it is removed and used as the base options. Those options are combined with an argument named "cnf" (which must be a dictionary) and finally combined with any other named argument. That is, it was (and still is) possible to write:

bbox = 2, 2, 347, 197
canvas.create_oval([bbox], {"fill" : "PeachPuff"})

instead of:

canvas.create_oval(bbox, fill="PeachPuff")

or even:

canvas.create_oval(2, 2, 347, 197, fill="PeachPuff")

In the end, the Tcl statement actually executed is like this:

.canvasname create oval 2 2 347 197 -fill PeachPuff

so it doesn't really matter how those parameters are passed.

But I'm unable to figure it out, so, what's correct (both? one?), and assuming it's the latter that's correct, would the first version still work in practice regardless of Python / Tkinter implementation?

I'd use the "modern" interface, that is, keyword arguments (instead of an explicit dictionary). Although the documentation warns against the "old" way, the fact is that Tkinter has changed very little in years, and the cnf parameter is still there in version 3.1

--
Gabriel Genellina

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to