Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Tkinter callback arguments

Reply
Thread Tools

Tkinter callback arguments

 
 
Lord Eldritch
Guest
Posts: n/a
 
      11-01-2009
Hi

Maybe this is maybe something it has been answered somewhere but I haven't
been able to make it work. I wanna pass one variable to a callback function
and I've read the proper way is:

Button(......, command=lambda: function(x))

So with

def function(a): print a

I get the value of x. Ok. My problem now is that I generate the widgets in a
loop and I use the variable to 'label' the widget:

for x in range(0,3): Button(......, command=lambda: function(x))

so pressing each button should give me 0,1,2.

But with the lambda, I always get the last index, because it gets actualized
at each loop cycle. Is there any way to get that?

Thanks in advance!
--
Lord Eldritch
 
Reply With Quote
 
 
 
 
MRAB
Guest
Posts: n/a
 
      11-01-2009
Lord Eldritch wrote:
> Hi
>
> Maybe this is maybe something it has been answered somewhere but I haven't
> been able to make it work. I wanna pass one variable to a callback function
> and I've read the proper way is:
>
> Button(......, command=lambda: function(x))
>
> So with
>
> def function(a): print a
>
> I get the value of x. Ok. My problem now is that I generate the widgets in a
> loop and I use the variable to 'label' the widget:
>
> for x in range(0,3): Button(......, command=lambda: function(x))
>
> so pressing each button should give me 0,1,2.
>
> But with the lambda, I always get the last index, because it gets actualized
> at each loop cycle. Is there any way to get that?
>

A lambda expression is just an unnamed function. At the point the
function is /called/ 'x' is bound to 3, so that's why 'function' is
always called with 3.

A function's default arguments are evaluated when the function is
/defined/, so you can save the current value of 'x' creating the
function (the lambda expression, in this case) with a default argument:

for x in range(0,3):
Button(......, command=lambda arg=x: function(arg))

The following will also work, although you might find the "x=x" a bit
surprising/confusing if you're not used to how Python works:

for x in range(0,3):
Button(......, command=lambda x=x: function(x))
 
Reply With Quote
 
 
 
 
Lord Eldritch
Guest
Posts: n/a
 
      11-02-2009
Alf P. Steinbach wrote:

> * MRAB:


Thank you all! It is working now nicely! God! I love usenet..
--
Lord Eldritch
 
Reply With Quote
 
eb303
Guest
Posts: n/a
 
      11-02-2009
On Nov 1, 8:53 pm, Lord Eldritch <(E-Mail Removed)> wrote:
> Hi
>
> Maybe this is maybe something it has been answered somewhere but I haven't
> been able to make it work. I wanna pass one variable to a callback function
> and I've read the proper way is:
>
> Button(......, command=lambda: function(x))
>
> So with
>
> def function(a): print a
>
> I get the value of x. Ok. My problem now is that I generate the widgets in a
> loop and I use the variable to 'label' the widget:
>
> for x in range(0,3): Button(......, command=lambda: function(x))
>
> so pressing each button should give me 0,1,2.
>
> But with the lambda, I always get the last index, because it gets actualized
> at each loop cycle. Is there any way to get that?


for x in range(0,3): Button(..., command=functools.partial(function,
x))

With the functools standard module that appeared in version 2.5, I
hardly ever use lambdas in Tkinter callbacks now.

> Thanks in advance!


HTH
 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      11-02-2009
Alf P. Steinbach wrote:

>> for x in range(0,3):
>> Button(......, command=lambda x=x: function(x))

>
> An alternative reusable alternative is to create a button-with-id class.
>
> This is my very first Python class so I'm guessing that there are all
> sorts of issues, in particular naming conventions.


Pseudo-private attributes, javaesque getter methods, unidiomatic None-
checks, broken naming conventions (**args), spaces in funny places...

> And the idea of creating a reusable solution for such a small issue may be
> un-pythonic?


Screw pythonic, the signal/noise ratio is awful in any language.

> But just as an example, in Python 3.x,


....for achieving less in more lines?

> <code>
> import tkinter
> # I guess for Python 2.x do "import Tkinter as tkinter" but haven't
> # tested.
>
>
> class IdButton( tkinter.Button ):
> def __init__( self, owner_widget, id = None, command = None, **args
> ):
> tkinter.Button.__init__(
> self, owner_widget, args, command = self.__on_tk_command
> )
> self.__id = id
> self.__specified_command = command
>
> def __on_tk_command( self ):
> if self.__specified_command != None:
> self.__specified_command( self )
> else:
> self.on_clicked()
>
> def on_clicked( self ):
> pass
> def id( self ):
> return self.__id
> def id_string( self ):
> return str( self.id() );
>
>
> def on_button_click( aButton ):
> print( "Button " + aButton.id_string() + " clicked!" )
>
> window = tkinter.Tk()
>
> n_buttons = 3
> for x in range( 1, n_buttons + 1 ):
> IdButton(
> window, id = x, text = "Button " + str( x ), command =
> on_button_click ).pack()
>
> window.mainloop()
> </code>


I'm not grumpy, I just don't like your code And I don't like the notion
that you are about to spread this style with your book...

Peter


 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      11-02-2009
* Peter Otten:
> Alf P. Steinbach wrote:
>
>>> for x in range(0,3):
>>> Button(......, command=lambda x=x: function(x))

>> An alternative reusable alternative is to create a button-with-id class.
>>
>> This is my very first Python class so I'm guessing that there are all
>> sorts of issues, in particular naming conventions.

>
> Pseudo-private attributes


That means there is some way of making attributes private?

Probably that comes across as an inane question but I ask it anyway. I haven't
really started to look at Python classes. I'm guessing that by asking here I may
learn things that are not obvious from the documentation.


>, javaesque getter methods,


What do you mean by that?

What I associate with Java getter method is mainly the "get" prefix, for Java
introspection.


> unidiomatic None-checks


What's the idiomatic Python way for an optional thing?

In this case one alternative I see could be to get rid of the __on_tc_command
method and more directly tell tkinter.Button to call the relevant function,
doing the if-else choice once only in the IdButton constructor.

Is that what you mean?

I'm thinking more in terms of customization points when I write code.

So I tend to avoid hardcoding things internally in methods, instead designing
the choices out to where they're accessible to client code.


>, broken naming conventions (**args),


How to do this argument forwarding in modern style?

Or is there an alternative to argument forwarding for this example?


> spaces in funny places...


Bah.


>> And the idea of creating a reusable solution for such a small issue may be
>> un-pythonic?

>
> Screw pythonic, the signal/noise ratio is awful in any language.
>
>> But just as an example, in Python 3.x,

>
> ...for achieving less in more lines?


Now, that's a good Python-independent question!

Re your question's the number of lines: /if/ the code is heavily reused then the
number of lines doesn't matter since they're only written /once/; the net effect
can even be to reduce the total number of lines, or at least the number of
apparent function points (or whatever size metric). That's part of what
"reusable" means. For example, if the OP used the code then he or she didn't
type them lines, but just copy/paste'd them, less work than typing in a lambda
definition in every button creation, and more clear code at every creation.

Re your question's what (the) reusability achieves.

First, when you and others have used such a thing in a number of places then you
gain confidence in correctness. For example, you don't wonder whether Python's
str type is correct, and when you test your program you don't test the str type
implementation. Since it's been used so much you know that it (mainly) is
correct, and that any remaining bug in there can't be all that serious, because
if it was then it would've surfaced in earlier use of the type.

This advantage of confidence in correctness can be realized even without heavy
reuse, because the encapsulation that's necessary for reuse, here having the
code in a class, also makes it possible with more centralized testing.

A centralized, encapsulated piece of code can be tested to death and deemed
correct (enough) and frozen, while the application of a code pattern in umpteen
places in umpteen programs, generally can't.

Second, when you do find a bug, or need more functionality, or whatever, there's
just /one place/ to fix/extend, whatever, instead of updating umpteen places in
umpteen programs, and trying to be sure that you've covered all instances and
done the right thing every place regardless of local variations (which is pretty
hopeless in general, but my experience with that kind of badness has mostly been
with C, not Python). More technically, it's reduced redundancy, in this case
avoiding redundant application of a code pattern everywhere one needs a button
with id (if that happens often). Reduced redundancy = good.

And third, as I mentioned, at every button creation, or in general every place
you'd use inline code rather than some reusable thing, you can get more clear
code, which can (but will not automatically ) reduce maintainance time.

But, the big drawback. It's easy to become enamoured by reusability and invest a
lot of work in encapsulation and general reusability, since it has those three
big desirable traits. But when what one creates is not actually reused then most
of that work can be /wasted/... For example, if the code only is used in 1
place, then the advantage of centralized testing is pretty moot unless that code
is changing for other reasons, for it doesn't matter much if you test it here or
there. It can be simpler to test it here, inline, than over there.

And another big drawback, but I believe it's less important in Python, that a
reusable thing can be less efficient because it can't take advantage of locally
available information and functionality each place where it's used, while inline
code that achieves the same (applying a pattern) can take advantage.


>> <code>
>> import tkinter
>> # I guess for Python 2.x do "import Tkinter as tkinter" but haven't
>> # tested.
>>
>>
>> class IdButton( tkinter.Button ):
>> def __init__( self, owner_widget, id = None, command = None, **args
>> ):
>> tkinter.Button.__init__(
>> self, owner_widget, args, command = self.__on_tk_command
>> )
>> self.__id = id
>> self.__specified_command = command
>>
>> def __on_tk_command( self ):
>> if self.__specified_command != None:
>> self.__specified_command( self )
>> else:
>> self.on_clicked()
>>
>> def on_clicked( self ):
>> pass
>> def id( self ):
>> return self.__id
>> def id_string( self ):
>> return str( self.id() );
>>
>>
>> def on_button_click( aButton ):
>> print( "Button " + aButton.id_string() + " clicked!" )
>>
>> window = tkinter.Tk()
>>
>> n_buttons = 3
>> for x in range( 1, n_buttons + 1 ):
>> IdButton(
>> window, id = x, text = "Button " + str( x ), command =
>> on_button_click ).pack()
>>
>> window.mainloop()
>> </code>

>
> I'm not grumpy, I just don't like your code And I don't like the notion
> that you are about to spread this style with your book...


He he. I've yet to acquire any Python style.


Cheers, & thanks,

- Alf
 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      11-02-2009
Alf P. Steinbach wrote:

> * Peter Otten:
>> Alf P. Steinbach wrote:
>>
>>>> for x in range(0,3):
>>>> Button(......, command=lambda x=x: function(x))
>>> An alternative reusable alternative is to create a button-with-id class.
>>>
>>> This is my very first Python class so I'm guessing that there are all
>>> sorts of issues, in particular naming conventions.

>>
>> Pseudo-private attributes

>
> That means there is some way of making attributes private?


No, there isn't. And the name mangled __attribute is hardly ever needed. Use
_attribute to convey the message "If you mess with this attribute you're on
your own".

> Probably that comes across as an inane question but I ask it anyway. I
> haven't really started to look at Python classes. I'm guessing that by
> asking here I may learn things that are not obvious from the
> documentation.
>
>
>>, javaesque getter methods,

>
> What do you mean by that?


In Java you have a private attribute and a public getter method. In Python
you can just make the attribute public, i. e.

# bad
class A:
def __init__(self):
self._id = 42
def id(self): return self._id

# good
class A:
def __init__(self):
self.id = 42

You can always switch to

class A: # assuming 3.x
@property
def id(self):
id = arbitrary_code()
return id

later.

> What I associate with Java getter method is mainly the "get" prefix, for
> Java introspection.
>
>
>> unidiomatic None-checks

>
> What's the idiomatic Python way for an optional thing?


if some_value is None: ...

> In this case one alternative I see could be to get rid of the
> __on_tc_command method and more directly tell tkinter.Button to call the
> relevant function, doing the if-else choice once only in the IdButton
> constructor.
>
> Is that what you mean?
>
> I'm thinking more in terms of customization points when I write code.
>
> So I tend to avoid hardcoding things internally in methods, instead
> designing the choices out to where they're accessible to client code.
>
>
>>, broken naming conventions (**args),

>
> How to do this argument forwarding in modern style?


I meant that keyword args are traditionally named kw or kwargs, the name
"args" is normally used for positional arguments:

def f(*args, **kw):
"whatever"

> Or is there an alternative to argument forwarding for this example?
>
>
>> spaces in funny places...

>
> Bah.
>
>
>>> And the idea of creating a reusable solution for such a small issue may
>>> be un-pythonic?

>>
>> Screw pythonic, the signal/noise ratio is awful in any language.
>>
>>> But just as an example, in Python 3.x,

>>
>> ...for achieving less in more lines?

>
> Now, that's a good Python-independent question!
>
> Re your question's the number of lines: /if/ the code is heavily reused
> then the number of lines doesn't matter since they're only written /once/;


Every time someone has to read the code he will read, hesitate, read again,
and then hopefully come to the conclusion that the code does nothing,
consider not using it, or if it is not tied into a larger project removing
it.

> the net effect can even be to reduce the total number of lines, or at
> least the number of apparent function points (or whatever size metric).
> That's part of what "reusable" means. For example, if the OP used the code
> then he or she didn't type them lines, but just copy/paste'd them, less
> work than typing in a lambda definition in every button creation, and more
> clear code at every creation.


But most of your code does *nothing*.

> Re your question's what (the) reusability achieves.
>
> First, when you and others have used such a thing in a number of places
> then you gain confidence in correctness. For example, you don't wonder
> whether Python's str type is correct, and when you test your program you
> don't test the str type implementation. Since it's been used so much you
> know that it (mainly) is correct, and that any remaining bug in there
> can't be all that serious, because if it was then it would've surfaced in
> earlier use of the type.


The theory may be OK, but in practice it doesn't always work out. Example:
Why do you introduce button.id_string() instead of str(button.id)? The
programmer will hesitate, wonder whether to use button.id() or
button.id_string(), how the two may interconnect...
It feels more like a hoop to jump through than a helpful service providing
tried an tested code.

> This advantage of confidence in correctness can be realized even without
> heavy reuse, because the encapsulation that's necessary for reuse, here
> having the code in a class, also makes it possible with more centralized
> testing.


Was this sentence/paragraph produced by http://pdos.csail.mit.edu/scigen/ ?

> A centralized, encapsulated piece of code can be tested to death and
> deemed correct (enough) and frozen, while the application of a code
> pattern in umpteen places in umpteen programs, generally can't.


I'd like to see a good test suite for your IdButton class, especially how it
copes with the design decision that you can override the on_clicked() stub,
or provide a command function, or both.

> Second, when you do find a bug, or need more functionality, or whatever,
> there's just /one place/ to fix/extend, whatever, instead of updating
> umpteen places in umpteen programs, and trying to be sure that you've
> covered all instances and done the right thing every place regardless of
> local variations (which is pretty hopeless in general, but my experience
> with that kind of badness has mostly been with C, not Python). More
> technically, it's reduced redundancy, in this case avoiding redundant
> application of a code pattern everywhere one needs a button with id (if
> that happens often). Reduced redundancy = good.


I agree with that maxim. Incidentally I have just found a nice example of
redundancy for you:

>>> def __on_tk_command( self ):
>>> if self.__specified_command != None:
>>> self.__specified_command( self )
>>> else:
>>> self.on_clicked()


Peter

 
Reply With Quote
 
Diez B. Roggisch
Guest
Posts: n/a
 
      11-02-2009
Alf P. Steinbach wrote:

> * Peter Otten:
>> Alf P. Steinbach wrote:
>>
>>>> for x in range(0,3):
>>>> Button(......, command=lambda x=x: function(x))
>>> An alternative reusable alternative is to create a button-with-id class.
>>>
>>> This is my very first Python class so I'm guessing that there are all
>>> sorts of issues, in particular naming conventions.

>>
>> Pseudo-private attributes

>
> That means there is some way of making attributes private?


No, it means that in Python we are consenting adults, and either respect
attributes with a leading underscore as private - or willfully chose to
*not* do that because of good reasons.

And the double-underscore is used against name-clashes, not for
enhanced "privacy".

>>, javaesque getter methods,

>
> What do you mean by that?
>
> What I associate with Java getter method is mainly the "get" prefix, for
> Java introspection.


You have an attribute id, whatfor do you need a method id? If at some point
this id becomes a computed value - you introduce a property

And that's what Peter meant with "javanesque" - the exact reason why in java
everything is wrapped in getters/setters is that the language lacks a
property-mechanism, so to present a consistent interface over several
iterations of the code, one has to introduce them for every single
attribute - regardless of their future destiny.

>
>> unidiomatic None-checks

>
> What's the idiomatic Python way for an optional thing?


None is a singleton, so the idiomatic check is for object identity:

foo = None
foo is None


Diez
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      11-02-2009
* Peter Otten:
> Alf P. Steinbach wrote:
>
>> * Peter Otten:
>>> Alf P. Steinbach wrote:
>>>
>>>>> for x in range(0,3):
>>>>> Button(......, command=lambda x=x: function(x))
>>>> An alternative reusable alternative is to create a button-with-id class.
>>>>
>>>> This is my very first Python class so I'm guessing that there are all
>>>> sorts of issues, in particular naming conventions.
>>> Pseudo-private attributes

>> That means there is some way of making attributes private?

>
> No, there isn't. And the name mangled __attribute is hardly ever needed. Use
> _attribute to convey the message "If you mess with this attribute you're on
> your own".


Thanks!


>> Probably that comes across as an inane question but I ask it anyway. I
>> haven't really started to look at Python classes. I'm guessing that by
>> asking here I may learn things that are not obvious from the
>> documentation.
>>
>>
>>> , javaesque getter methods,

>> What do you mean by that?

>
> In Java you have a private attribute and a public getter method. In Python
> you can just make the attribute public, i. e.
>
> # bad
> class A:
> def __init__(self):
> self._id = 42
> def id(self): return self._id
>
> # good
> class A:
> def __init__(self):
> self.id = 42


I think I get the gist that locally saving lines of code, and generally avoiding
having to write empty argument list parentheses, and thereby also indicating in
a way that one is accessing a logical data attribute, is considered good in
Python, which goes to initial development time and the amount of code that one
must scan to grok it both for definition and usage -- is that correct?

But the trade-off is inviting modification of a supposedly fixed id, which goes
to correctness and later fix-it time?


> You can always switch to
>
> class A: # assuming 3.x
> @property
> def id(self):
> id = arbitrary_code()
> return id
>
> later.


Thanks, now I learned about @property...

But when the thing has been used it's much more difficult to restrict the
functionality (making read-only, breaking code that changes id) than to add
functionality (making also writeable, breaking none of existing code).

So isn't "later" a bit late to make it read-only, shouldn't that be the initial
design, and then possibly adding a setter later if id's turn out to not be so
constant after all?


>> What I associate with Java getter method is mainly the "get" prefix, for
>> Java introspection.
>>
>>
>>> unidiomatic None-checks

>> What's the idiomatic Python way for an optional thing?

>
> if some_value is None: ...


Thanks!

But why is this preferred?


>> In this case one alternative I see could be to get rid of the
>> __on_tc_command method and more directly tell tkinter.Button to call the
>> relevant function, doing the if-else choice once only in the IdButton
>> constructor.
>>
>> Is that what you mean?
>>
>> I'm thinking more in terms of customization points when I write code.
>>
>> So I tend to avoid hardcoding things internally in methods, instead
>> designing the choices out to where they're accessible to client code.
>>
>>
>>> , broken naming conventions (**args),

>> How to do this argument forwarding in modern style?

>
> I meant that keyword args are traditionally named kw or kwargs, the name
> "args" is normally used for positional arguments:
>
> def f(*args, **kw):
> "whatever"


Thanks!

*Note to myself*: check if there are more such conventions.


>> Or is there an alternative to argument forwarding for this example?
>>
>>
>>> spaces in funny places...

>> Bah.
>>
>>
>>>> And the idea of creating a reusable solution for such a small issue may
>>>> be un-pythonic?
>>> Screw pythonic, the signal/noise ratio is awful in any language.
>>>
>>>> But just as an example, in Python 3.x,
>>> ...for achieving less in more lines?

>> Now, that's a good Python-independent question!
>>
>> Re your question's the number of lines: /if/ the code is heavily reused
>> then the number of lines doesn't matter since they're only written /once/;

>
> Every time someone has to read the code he will read, hesitate, read again,
> and then hopefully come to the conclusion that the code does nothing,
> consider not using it, or if it is not tied into a larger project removing
> it.


I don't understand what you mean.

Not that it's a shiny example of code that does a lot, but it (1) simplifies and
shortens creation of buttons with id, and (2) provides a nice start for adding
other customizations of those buttons, and (3) supports searching for a button
with given command id, e.g. for purpose of hiding or enable/disable.

If I didn't just want to try out writing a Python class, which I've never done
before so it appeared interesting, I'd probably just skipped points 2 and 3 and
written the same functionality as a factory function, like


<code>
import tkinter

def id_button( owner_widget, id, command = None, **kwargs ):
def tk_command( an_id = id, a_command = command ):
if a_command is not None: a_command( id )
return tkinter.Button( owner_widget, kwargs, command = tk_command )

def on_button_click( id ):
print( "Button " + str( id ) + " clicked!" )

window = tkinter.Tk()

n_buttons = 3
for x in range( 1, n_buttons + 1 ):
id_button(
window, id = x, text = "Button " + str( x ), command = on_button_click
).pack()

window.mainloop()
</code>


but once you have the class, for whatever reason, it would be silly not to use
it, especially since it provides points 2 and 3 which the function doesn't.

By the way, I as yet know next to *nothing* about binding of variable references
within a function such as tk_command above. Probably I've done Unnecessary
Things(TM) above?


>> the net effect can even be to reduce the total number of lines, or at
>> least the number of apparent function points (or whatever size metric).
>> That's part of what "reusable" means. For example, if the OP used the code
>> then he or she didn't type them lines, but just copy/paste'd them, less
>> work than typing in a lambda definition in every button creation, and more
>> clear code at every creation.

>
> But most of your code does *nothing*.


See above, points 2 and 3. Most of that class has to do with 2, customization
ability.


>> Re your question's what (the) reusability achieves.
>>
>> First, when you and others have used such a thing in a number of places
>> then you gain confidence in correctness. For example, you don't wonder
>> whether Python's str type is correct, and when you test your program you
>> don't test the str type implementation. Since it's been used so much you
>> know that it (mainly) is correct, and that any remaining bug in there
>> can't be all that serious, because if it was then it would've surfaced in
>> earlier use of the type.

>
> The theory may be OK, but in practice it doesn't always work out. Example:
> Why do you introduce button.id_string() instead of str(button.id)?


Because the string representation of an id then /can/ be customized
independently of the id. For example, id's might be integers but for string
representation you might want symbolic action names (e.g., you might have two or
more buttons with same title but different actions, so that title would be
ungood to identify button). And for another example, when debugging or testing
you might want the string represention of an id to provide more information
about the button and/or its context, and then id_string provides a single
central customization point -- provided it's used, of course. <g>


> The
> programmer will hesitate, wonder whether to use button.id() or
> button.id_string(), how the two may interconnect...


Hm, see immediately above.

It's perhaps a different way of thinking?


> It feels more like a hoop to jump through than a helpful service providing
> tried an tested code.


Yes.

It's the old "every computer science problem can be solved by adding an extra
layer of indirection".

Sometimes it's nice when you can do that centrally. Retrofitting the indirection
to existing client code can be hard.


>> This advantage of confidence in correctness can be realized even without
>> heavy reuse, because the encapsulation that's necessary for reuse, here
>> having the code in a class, also makes it possible with more centralized
>> testing.

>
> Was this sentence/paragraph produced by http://pdos.csail.mit.edu/scigen/ ?


No. But you're right that testing isn't that much of an issue for that
class. If that's what you meant.


>> A centralized, encapsulated piece of code can be tested to death and
>> deemed correct (enough) and frozen, while the application of a code
>> pattern in umpteen places in umpteen programs, generally can't.

>
> I'd like to see a good test suite for your IdButton class, especially how it
> copes with the design decision that you can override the on_clicked() stub,
> or provide a command function, or both.


The design is that for any given IdButton there's a single point of
responsibility for the click action, namely either a button creation code
supplies that action, or it relies on the action defined in the class.

I.e. again customization ability, that the button creation code can /override/
the class provided action, per button, without getting into general overriding
of class methods, just by defining a nice little lambda inline in the call.

But as I learn more Python I may perhaps find that overriding class methods can
also be done that conveniently -- I don't know, keep in mind I'm a Python
newbie, and doing Very Much Else than studying Python.


>> Second, when you do find a bug, or need more functionality, or whatever,
>> there's just /one place/ to fix/extend, whatever, instead of updating
>> umpteen places in umpteen programs, and trying to be sure that you've
>> covered all instances and done the right thing every place regardless of
>> local variations (which is pretty hopeless in general, but my experience
>> with that kind of badness has mostly been with C, not Python). More
>> technically, it's reduced redundancy, in this case avoiding redundant
>> application of a code pattern everywhere one needs a button with id (if
>> that happens often). Reduced redundancy = good.

>
> I agree with that maxim. Incidentally I have just found a nice example of
> redundancy for you:
>
>>>> def __on_tk_command( self ):
>>>> if self.__specified_command != None:
>>>> self.__specified_command( self )
>>>> else:
>>>> self.on_clicked()

>


Uh, could you expand on how that's redundant and how to make it less so?


Cheers, & thanks,

- Alf
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      11-02-2009
* Diez B. Roggisch:
> Alf P. Steinbach wrote:
>
>> * Peter Otten:
>>> Alf P. Steinbach wrote:
>>>
>>>>> for x in range(0,3):
>>>>> Button(......, command=lambda x=x: function(x))
>>>> An alternative reusable alternative is to create a button-with-id class.
>>>>
>>>> This is my very first Python class so I'm guessing that there are all
>>>> sorts of issues, in particular naming conventions.
>>> Pseudo-private attributes

>> That means there is some way of making attributes private?

>
> No, it means that in Python we are consenting adults, and either respect
> attributes with a leading underscore as private - or willfully chose to
> *not* do that because of good reasons.


Hm. But thanks! That's very useful information -- now I'll not be going on a
wild goose chase!


> And the double-underscore is used against name-clashes, not for
> enhanced "privacy".
>
>>> , javaesque getter methods,

>> What do you mean by that?
>>
>> What I associate with Java getter method is mainly the "get" prefix, for
>> Java introspection.

>
> You have an attribute id, whatfor do you need a method id? If at some point
> this id becomes a computed value - you introduce a property
>
> And that's what Peter meant with "javanesque" - the exact reason why in java
> everything is wrapped in getters/setters is that the language lacks a
> property-mechanism, so to present a consistent interface over several
> iterations of the code, one has to introduce them for every single
> attribute - regardless of their future destiny.


Thanks again for useful information.

Also Peter mentioned this about changing simple attributes into properties at
later time, so that seems to at least not be unheard of in Python?

Your comment about "computed" makes it more clear what that's all about. Also
Bertrand Meyer (Eiffel language creator) had idea like that, he called it
"referential transparency". But I think when Python has this nice property
mechanism, why do people change direct data attributes into properties and not
the other way around or not at all, I mean using only properties for logical
data attributes -- e.g. assuring correctness first via read-only property?


>>> unidiomatic None-checks

>> What's the idiomatic Python way for an optional thing?

>
> None is a singleton, so the idiomatic check is for object identity:
>
> foo = None
> foo is None


Again, thanks, that helps me understand the rationale. Although not completely.
But there is a connection...


Cheers,

- Alf
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Passing arguments to callback function in addEventListener Janus Javascript 10 01-11-2007 01:23 PM
OOP: dynamic arguments in callback functions? Tyler Javascript 2 05-22-2006 06:39 AM
already written optparse callback for range and list arguments? Alex Gittens Python 1 07-10-2005 02:22 AM
Tkinter callback caused abnormal program termination John Pote Python 2 11-11-2004 09:45 AM



Advertisments