events/callbacks - best practices

H

HankC

Greetings:

I'm been programming Delphi for a while and am trying to get into the
Python mindset. In Delphi, you can have a component class that has
properties, methods, and events. Properties and methods translate
pretty easily to Python but I'm not sure about the best way to handle
events. For example, from fxn retrbinary in ftplib there is:

while 1:
data = conn.recv(blocksize)
if not data:
break
callback(data)
conn.close()

In delphi this would be something like:

while 1:
data = conn.recv(blocksize)
if not data:
break
if assigned(OnProgress) then
callback(data)
conn.close()

In other words, the class can handle a number of events but passing a
callback function is not mandatory. If you want to handle an event,
it is assigned and dealt with.

I'm especially interested in non-visual components (like the ftplib)
and the examples I can find all deal with the events of visual
components that interjects more complexity than I'd like at this stage
of my knowledge.

My goal is to rewrite a number of non visual components in Python.
What I'd like to find is a 'non visual component design in Python'
guide somewhere. So... I'm more than willing to study if I can find
the resources - if you have any please lay them on me! Part of my
problem, I'm sure, is poor terminology use.

Of course, any general comments are welcomed - I'm not really
expecting a tutorial here, though :)

Thanks!
 
E

Erik Max Francis

HankC said:
In delphi this would be something like:

while 1:
data = conn.recv(blocksize)
if not data:
break
if assigned(OnProgress) then
callback(data)
conn.close()

In other words, the class can handle a number of events but passing a
callback function is not mandatory. If you want to handle an event,
it is assigned and dealt with.

It's not fully clear to me exactly what you're asking, but it sounds
like the general answer is that the "callback" that you pass in can be
as complex as you want. Call it `handler':

handler.startProcessing()
while True:
data = ... get more
if not data and handler.notFinished():
break
if handler.acceptsData():
handler.accept(data)
conn.cloes()
handler.doneProcessing()
 
P

Peter Otten

HankC said:
Greetings:

I'm been programming Delphi for a while and am trying to get into the
Python mindset. In Delphi, you can have a component class that has
properties, methods, and events. Properties and methods translate
pretty easily to Python but I'm not sure about the best way to handle
events. For example, from fxn retrbinary in ftplib there is:

while 1:
data = conn.recv(blocksize)
if not data:
break
callback(data)
conn.close()

In delphi this would be something like:

while 1:
data = conn.recv(blocksize)
if not data:
break
if assigned(OnProgress) then
callback(data)
conn.close()

In other words, the class can handle a number of events but passing a
callback function is not mandatory. If you want to handle an event,
it is assigned and dealt with.

I'm especially interested in non-visual components (like the ftplib)
and the examples I can find all deal with the events of visual
components that interjects more complexity than I'd like at this stage
of my knowledge.

My goal is to rewrite a number of non visual components in Python.
What I'd like to find is a 'non visual component design in Python'
guide somewhere. So... I'm more than willing to study if I can find
the resources - if you have any please lay them on me! Part of my
problem, I'm sure, is poor terminology use.

Of course, any general comments are welcomed - I'm not really
expecting a tutorial here, though :)

Thanks!

As of C++ Builder 3, Delphi events are just function pointers with IDE
support. IMHO it is useless to replicate this mechanism in Python. Just
make a base class with empty methods instead. Override instead of using
function pointers, if the behaviour need not change at runtime.

# delphi style, as far as I remember.
# now say this isn't bloated with a straight face :)
class TDelphi:
def __init__(self):
self.OnStart = None
def start(self):
if self.OnStart:
self.OnStart(self)


d = TDelphi() # IDE

# callback would typically be a method of a form
class Form:
def MyOnStart(self, sender): # prototype generated by IDE
print "start 0"

f = Form() # IDE
d.OnStart = f.MyOnStart # IDE
d.start()

# oo style
class OO:
def start(self):
pass

# use case 1
o = OO()
def start():
print "start 1"
o.start = start
o.start()

# use case 2
class Override(OO):
def start(self):
print "start 2"
o = Override()
o.start()

Peter
 
A

anton muhin

HankC said:
Greetings:

I'm been programming Delphi for a while and am trying to get into the
Python mindset. In Delphi, you can have a component class that has
properties, methods, and events. Properties and methods translate
pretty easily to Python but I'm not sure about the best way to handle
events. For example, from fxn retrbinary in ftplib there is:

while 1:
data = conn.recv(blocksize)
if not data:
break
callback(data)
conn.close()

In delphi this would be something like:

while 1:
data = conn.recv(blocksize)
if not data:
break
if assigned(OnProgress) then
callback(data)
conn.close()

In other words, the class can handle a number of events but passing a
callback function is not mandatory. If you want to handle an event,
it is assigned and dealt with.

I'm especially interested in non-visual components (like the ftplib)
and the examples I can find all deal with the events of visual
components that interjects more complexity than I'd like at this stage
of my knowledge.

My goal is to rewrite a number of non visual components in Python.
What I'd like to find is a 'non visual component design in Python'
guide somewhere. So... I'm more than willing to study if I can find
the resources - if you have any please lay them on me! Part of my
problem, I'm sure, is poor terminology use.

Of course, any general comments are welcomed - I'm not really
expecting a tutorial here, though :)

Thanks!

It's not clear what precisely you are looking for, but just some ideas:

class Foo(object):
def __init__(self):
self.__callback = None

def set_callback(self, callback):
self.__callback = callback

def fire(self, *args, **kw):
if self.__callback:
return self.__callback(*args, **kw)
else:
return self.default_callback(*args, **kw)

def default_callback(self, *args, **kw):
return "default_callback(%s, %s)" % (args, kw)

foo = Foo()
print foo.fire("me", bar = "oops")

def callback(*args, **kw):
return "callback(%s, %s)" % (args, kw)

foo.set_callback(callback)
print foo.fire("you", oops = "foo")


Properties may be even fancier. __call__ method might be useful too.

hth,
anton.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top