470,815 Members | 2,263 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,815 developers. It's quick & easy.

any trick to allow anonymous code blocks in python?

Is there any metaclass trick or something similar to allow anonymous
code blocks?

I'd like to be able to let users do something like this fictitious example:
b = Button()
b.OnClick =:
print "you clicked me"

But that would require adding a special "=:" operator to bind a code
block to a function.
Is there any PEP for something like that? I see 310 might allow:
b=Button()
with b.OnClick:
print "you clicked me"

I know I can already do it like these examples:
def OnClick(self,event):
print "you clicked me"
b.OnClick = OnClick
or
b = Button(OnClick=OnClick)
or subclassing Button.
Jul 18 '05 #1
20 1817
"Doug Holton" <in****@spam.here> wrote in message
news:v6********************@comcast.com...
Is there any metaclass trick or something similar to allow anonymous
code blocks?

I'd like to be able to let users do something like this fictitious example: b = Button()
b.OnClick =:
print "you clicked me"


No. If you're looking for GUI callbacks, there's a significant
gap between lambdas and bound methods. You could
use something like (not tested):

b.OnClick = (lambda : sys.stdout("You clicked me"))

which will work (assuming I've got the syntax right).

If you're doing anything other than a toy program, though,
the best approach is to wrap the GUI widget in a class,
and use a bound method of that class for the callbacks.

The example in the Tkinter chapter of the Python Library
Reference (16.1.2.2 in the Python 2.3.3 docs) shows
how to do it. It's amazingly simple, it's completely object
oriented, and it gives you full access to the instance within
the callback.

John Roth
Jul 18 '05 #2
lambda?
Jul 18 '05 #3
Tyler Eaves wrote:
lambda?


Looks like, since it does not put a name on the
function. But there is anyway a function object
created, not just a code object.
The similar to using an unnamed lambda is
defining a function, bindin it into some context,
and deleting it immediately.
There is no difference, in principle.

--
Christian Tismer :^) <mailto:ti****@stackless.com>
Mission Impossible 5oftware : Have a break! Take a ride on Python's
Johannes-Niemeyer-Weg 9a : *Starship* http://starship.python.net/
14109 Berlin : PGP key -> http://wwwkeys.pgp.net/
work +49 30 89 09 53 34 home +49 30 802 86 56 mobile +49 173 24 18 776
PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04
whom do you want to sponsor today? http://www.stackless.com/
Jul 18 '05 #4
Doug Holton wrote:
Is there any metaclass trick or something similar to allow anonymous
code blocks?

I'd like to be able to let users do something like this fictitious example:
b = Button()
b.OnClick =:
print "you clicked me"


What exactly do you want to do?
Why is defining a function too much for you?
I can't see it is your problem since you are a Python programmer
(or you would not ask for metaclass tricks) :-)

Looks like a problem with an interface for users.
Do you want to make the definition
of actions in a GUI simpler for your users?

In the latter case, it is probably simplest to define
a smallish sub-language by a few rules, and create
proper Python functions at initialization time?

Feel free to contact me in private email if I'm right.

ciao - chris

p.s.: But please give me a real email address. I have no time
to guess.
--
Christian Tismer :^) <mailto:ti****@stackless.com>
Mission Impossible 5oftware : Have a break! Take a ride on Python's
Johannes-Niemeyer-Weg 9a : *Starship* http://starship.python.net/
14109 Berlin : PGP key -> http://wwwkeys.pgp.net/
work +49 30 89 09 53 34 home +49 30 802 86 56 mobile +49 173 24 18 776
PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04
whom do you want to sponsor today? http://www.stackless.com/
Jul 18 '05 #5
John Roth wrote:
Is there any metaclass trick or something similar to allow anonymous
code blocks?
.... No. If you're looking for GUI callbacks, there's a significant
gap between lambdas and bound methods. You could
use something like (not tested):

b.OnClick = (lambda : sys.stdout("You clicked me"))
Yeah, I didn't mention the lambda option. I was thinking about
designing a framework meant for beginners, and I'd rather stay away from
lambdas. I'm surprised no one is even proposing support for anonymous
code blocks in Python that support multiple lines, similar to what Ruby,
Java, and other languages have.
If you're doing anything other than a toy program, though,
the best approach is to wrap the GUI widget in a class,
and use a bound method of that class for the callbacks.


Right, that is the subclass example I mentioned in the original note,
but I didn't spell it out:
class MyButton(Button):
def OnClick(self,event):
print "you clicked me"
b = MyButton()
I already know that will work, and that is what I would use myself, and
it is more elegant than lambdas. I was just looking to see if anyone
had a hack for anonymous code blocks, but thankyou for your help.
Jul 18 '05 #6
Christian Tismer wrote:
Looks like a problem with an interface for users.
Do you want to make the definition
of actions in a GUI simpler for your users?
Right, that is what I was trying to do.
In the latter case, it is probably simplest to define
a smallish sub-language by a few rules, and create
proper Python functions at initialization time?


That's a great goal, creating a simplified python dialect that can be
converted to regular Python syntax and bytecode. It's a little outside
of my reach right now though. And prothon which was mentioned recently
is incompatible with the python "virtual machine".

I just saw recently someone made a bytecode hack to allow for decorators
in Python:
http://aspn.activestate.com/ASPN/Coo.../Recipe/286147
and I just thought I'd ask if anyone had done anything similar to allow
for code blocks, but I guess not. No big deal.
Jul 18 '05 #7
Doug Holton wrote:
Is there any metaclass trick or something similar to allow anonymous
code blocks?

I'd like to be able to let users do something like this fictitious example:
b = Button()
b.OnClick =:
print "you clicked me"

But that would require adding a special "=:" operator to bind a code
block to a function.
Why can't b.OnClick simply be a handle for a function encapsulating that
statement?
Is there any PEP for something like that? I see 310 might allow:
b=Button()
with b.OnClick:
print "you clicked me"

I know I can already do it like these examples:
def OnClick(self,event):
print "you clicked me"
b.OnClick = OnClick
or
b = Button(OnClick=OnClick)
or subclassing Button.


Then what's the problem? wxPython allows you to Bind() functions to
events. Why obfuscate the code with unnecessary statements?
Jul 18 '05 #8
In article <RO********************@comcast.com>,
Doug Holton <in****@spam.here> wrote:
b.OnClick = (lambda : sys.stdout("You clicked me"))


Yeah, I didn't mention the lambda option. I was thinking about
designing a framework meant for beginners, and I'd rather stay away from
lambdas. I'm surprised no one is even proposing support for anonymous
code blocks in Python that support multiple lines, similar to what Ruby,
Java, and other languages have.


Presumably the right (but non-Python) syntax for such a code block would
be:

def b.onClick():
print "You clicked me"

One reason for not adding this to Python would be the difficulty of
determining where the expression for the def'd object ends and where the
argument list for its definition begins. One could imagine working
backwards from the colon but I don't think Python's parser can do that,
and anyway if it's difficult for machines to parse it's also difficult
for humans to read.

--
David Eppstein http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
Jul 18 '05 #9
David Eppstein wrote:
In article <RO********************@comcast.com>,
Doug Holton <in****@spam.here> wrote:

b.OnClick = (lambda : sys.stdout("You clicked me"))


Yeah, I didn't mention the lambda option. I was thinking about
designing a framework meant for beginners, and I'd rather stay away from
lambdas. I'm surprised no one is even proposing support for anonymous
code blocks in Python that support multiple lines, similar to what Ruby,
Java, and other languages have.

Presumably the right (but non-Python) syntax for such a code block would
be:

def b.onClick():
print "You clicked me"

One reason for not adding this to Python would be the difficulty of
determining where the expression for the def'd object ends and where the
argument list for its definition begins. One could imagine working
backwards from the colon but I don't think Python's parser can do that,
and anyway if it's difficult for machines to parse it's also difficult
for humans to read.


Plus there's little difference between that and:

def onClick(self):
print "You clicked me"

where this is a class method. It's redundant notation and contrary to
Python's "there should be one-- and preferably only one --obvious way to
do it" philosophy.
Jul 18 '05 #10

"Doug Holton" <in****@spam.here> wrote
That's a great goal, creating a simplified python dialect that can be
converted to regular Python syntax and bytecode. It's a little outside
of my reach right now though. And prothon which was mentioned recently
is incompatible with the python "virtual machine".


I'm not trolling for Prothon users, since Prothon isn't ready for use
anyway, but I'm curious why you have to use the Python intepreter. Can you
fill me in?

Prothon by the way doesn't have anonymous code blocks, but it can do:

b = button()
def b.onClick():
print "You clicked me"

Is that what you wanted?
Jul 18 '05 #11
Mark Hahn wrote:
Prothon by the way doesn't have anonymous code blocks, but it can do:

b = button()
def b.onClick():
print "You clicked me"
That's the alternative David Eppstein mentioned, and I like it even
better than my =: suggestion ( b.onclick =: <code block> ).

Perhaps that should be a proposal for Python. It's like the decorators
proposal (318). It just saves an extra step and is helpful for
framework designers (people who use metaclasses, etc.). Instead of
having to do this (or the other ways I mentioned):
def onclick(..):
...code here
b.onclick = onclick

You can save a step and just do like you said:
def b.onclick(...):
...code here

Similarly, decorators will save a step: (exact syntax TBD)
def myfunc (params) [synchronized]:
...
instead of:
def myfunc (params):
...
myfunc = synchronized(myfunc)

I'm not trolling for Prothon users, since Prothon isn't ready for use
anyway, but I'm curious why you have to use the Python intepreter. Can you fill me in?


You know better than me, but last I checked, in prothon you can't use
any of the wealth of python bindings to 3rd-party code libraries.
Perhaps eventually either prothon could be made compatible with python,
or SWIG/Boost/Pyrex etc. could be made compatible with prothon so that
it would be easy for example to compile wxpython for prothon. wxprothon.
Jul 18 '05 #12
Doug Holton wrote:
Mark Hahn wrote:
I'm not trolling for Prothon users, since Prothon isn't ready for
use anyway, but I'm curious why you have to use the Python
intepreter. Can you fill me in?


You know better than me, but last I checked, in prothon you can't use
any of the wealth of python bindings to 3rd-party code libraries.
Perhaps eventually either prothon could be made compatible with
python, or SWIG/Boost/Pyrex etc. could be made compatible with
prothon so that it would be easy for example to compile wxpython for
prothon. wxprothon.


Oh, ok. I thought you meant there was some inherent reason you had to use
the Python interpreter no matter what.

When I said Prothon wasn't ready I was including lack of 3rd-party libraries
as one reason. We hope to have all the big ones on board by early next
year. SWIG, Boost etc. will be the obvious places to start to get leverage
on a lot of libs.

We plan to have wxWidgets (what used to be wxWindows) as our standard GUI
when we release 1.0 late this year. The only thing keeping it from being
our standard might be how hard it is to install on Linux.

In any case we will have our own wrapper for wxWidgets. We hope to have
cool new wxWidget wrapper features that take advantage of our native OS
threads and some of our unique language features like functions-as-commands
and caller access (kind of like macros).

It's easy to brag about it now. We haven't started on it yet. :-)
Jul 18 '05 #13
Doug Holton wrote:
Mark Hahn wrote:
> Prothon by the way doesn't have anonymous code blocks, but it can

do: >
> b = button()
> def b.onClick():
> print "You clicked me"


That's the alternative David Eppstein mentioned, and I like it even
better than my =: suggestion ( b.onclick =: <code block> ).


FYI...

If you don't need b, you could also do this:

def button().onClick():
print "You clicked me"

If you need b and you want to write compact (some would argue Perl-like)
code, you could use a new syntax we are debating right now that allows
assignments-as-expressions with ":=".

def (b := button()).onClick(): print "You clicked me"

There are valid non-Perl-like uses for := also. :-)
Jul 18 '05 #14
Christian Tismer <ti****@stackless.com> writes:
What exactly do you want to do?
Why is defining a function too much for you?


One argument for "anonymous functions to be assigned to another
object" is that defining such functions "pollute" the namespace with
names that only serve one purpose, yet remain in some scope where they
are no longer needed unless you delete them.

def myAction():
print "You clicked me"

b.OnClick = myAction

del(myAction)

etc.
Jul 18 '05 #15
Doug Holton wrote:
Is there any metaclass trick or something similar to allow anonymous
code blocks?

I'd like to be able to let users do something like this fictitious
example: b = Button()
b.OnClick =:
print "you clicked me"

But that would require adding a special "=:" operator to bind a code
block to a function.
Is there any PEP for something like that? I see 310 might allow:
b=Button()
with b.OnClick:
print "you clicked me"

I know I can already do it like these examples:
def OnClick(self,event):
print "you clicked me"
b.OnClick = OnClick
or
b = Button(OnClick=OnClick)
or subclassing Button.


Maybe you can use something as simple as a naming convention, i. e.
automatically associate a function b1OnClick() with a button b1:

import types

class Widget:
pass

class Button(Widget):
def __init__(self, name):
self.name = name

def makeMethod(widget, methodname, function):
setattr(widget, methodname, lambda: function(widget))

def collectMethods():
ns = globals()
widgets = []
functions = []
for n, i in ns.items():
if isinstance(i, Widget):
widgets.append((n, i))
elif isinstance(i, types.FunctionType):
functions.append((n, i))

for fn, f in functions:
for wn, w in widgets:
if fn.startswith(wn):
makeMethod(w, fn[len(wn):], f)
break

#begin client code
b1 = Button("one")
b2 = Button("two")
b3 = Button("three")

def b1OnClick(self):
print "you clicked button 1"

def b2OnClick(self):
print "you clicked button %s" % self.name

b3OnClick = b2OnClick
#end client code

collectMethods()
b1.OnClick()
b2.OnClick()
b3.OnClick()

Jul 18 '05 #16
Mark Hahn wrote:
In any case we will have our own wrapper for wxWidgets. We hope to have
cool new wxWidget wrapper features that take advantage of our native OS
threads and some of our unique language features like functions-as-commands
and caller access (kind of like macros).


One thing to be aware of is that wxPython actually has a fair amount
of widgets coded entirely in Python. That means you get to lack
some of it, or have to re-implement it.

An example of a nice one is the maskededit. Obviously you won't
need to duplicate all of them, but they do exist since they were
useful to enough people for Robin to include them.

And the biggest issue with wxPython users seems to have been the
documentation. There are some people who find the C++ derived
doc as unPythonic and unreadable. Robin has been doing all sorts
of clever stuff with SWIG to try and make the __doc__ be useful
although method signatures still aren't (they are all *args, **kwargs).

It would be interesting to see the Prothon version of the wxPython
demo. If you were a real masochist you could do one showing the
Python demo code and the corresponding Prothon demo code side
by side to demonstrate which one is better :-)

Roger
Jul 18 '05 #17
il Sat, 26 Jun 2004 00:58:49 -0500, Doug Holton <in****@spam.here> ha
scritto::
Perhaps that should be a proposal for Python. It's like the decorators
proposal (318). It just saves an extra step and is helpful for
framework designers (people who use metaclasses, etc.). Instead of
having to do this (or the other ways I mentioned):
def onclick(..):
...code here
b.onclick = onclick

You can save a step and just do like you said:
def b.onclick(...):
...code here


just my two cents: you can do this in ruby with nearly the same
syntax:
def b.onkclick()
..code here..
end

But even if that sounds like a great idea I have to admit it's not
widely used, probably because every framework with callbacks like
these already uses the common bind-a-function-to-this-event idiom,
instead of allowing method overriding.

Maybe this relates to the fact that GUI toolkits are mostly C/C++
based, and that years of limited languages have directed our mind
toward the 'you have to subclass' dictat. I wonder if SmallTalk GUIs
have something like this.

It would be nice to have singleton method definition with this syntax
in python, anyway.
Jul 18 '05 #18
> Maybe this relates to the fact that GUI toolkits are mostly C/C++
based, and that years of limited languages have directed our mind
toward the 'you have to subclass' dictat. I wonder if SmallTalk GUIs
have something like this.

Smalltalk supports inline anonymous code blocks, looking something like:

mylist sort: [ :a :b | b-a ]

invokes the sort message on mylist, using a code block with two arguments, a
and b, using b-a as the comparison (implements a descending order sort).

-- Paul
Jul 18 '05 #19
"Doug Holton" <in****@spam.here> wrote in message
news:RO********************@comcast.com...
John Roth wrote:
Is there any metaclass trick or something similar to allow anonymous
code blocks?

...
No. If you're looking for GUI callbacks, there's a significant
gap between lambdas and bound methods. You could
use something like (not tested):

b.OnClick = (lambda : sys.stdout("You clicked me"))


Yeah, I didn't mention the lambda option. I was thinking about
designing a framework meant for beginners, and I'd rather stay away from
lambdas. I'm surprised no one is even proposing support for anonymous
code blocks in Python that support multiple lines, similar to what Ruby,
Java, and other languages have.


It's been proposed a number of times, and you can find the
discussions (some of which amount to flame wars) by searching
Google Groups.

IIRC, there are two fundamental issues. One is syntax: it's not easy
to find a decent syntax that looks good, lets you shift back to statement
level from expression level, and handles blocks for each parameter
of a method.

The other issue is that blocks themselves don't do all that much.
Ruby's facility with blocks actually comes from the very nice
intersection of several features, including the pervasive implementation
of the visitor pattern in all collection objects and the provision of
a block as a special parameter. There are a couple of other
features that also help. Blocks without those other features
wouldn't do what Ruby does.

The same thing is true of, for example, Smalltalk. Blocks
have to be seen in the context of the entire language.

John Roth
Jul 18 '05 #20
il Sat, 26 Jun 2004 10:54:27 GMT, "Paul McGuire"
<pt***@austin.stopthespam_rr.com> ha scritto::
Smalltalk supports inline anonymous code blocks, looking something like:

mylist sort: [ :a :b | b-a ]

invokes the sort message on mylist, using a code block with two arguments, a
and b, using b-a as the comparison (implements a descending order sort).


thank you, I knew this, but I was thinking about something else:

It seem to me that SmallTalk has singleton instance methods just like
ruby and python. Given that GUIs are tightly integrated with the ST
environment (while python uses toolkits that are mainly developed in
other languages like C ), It would be reasonable to see something on
the lines of what the OP was asking, like:

def b.onclick:
foo

Or do you mean that everything in ST gui code is done via

button when: #clicked do: [blockClosure]

?
Jul 18 '05 #21

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

699 posts views Thread by mike420 | last post: by
76 posts views Thread by Nick Coghlan | last post: by
134 posts views Thread by Joseph Garvin | last post: by
29 posts views Thread by John Rivers | last post: by
reply views Thread by mihailmihai484 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.