From: Robert Kern on
On 2010-04-05 12:08 PM, John Nagle wrote:
> Alf P. Steinbach wrote:
>
>> Best is however to recognize that you have some state (your variable)
>> and some operations on that state (your callback), and that that is
>> what objects are all about. I.e. wrap your logic in a class. Then
>> 'lastModifiedTime' becomes an instance attribute, and 'handler'
>> becomes a method.
>>
>> It doesn't matter that there will only ever be one object (instance)
>> of that class.
>>
>> Classes were meant for just this sort of thing, state + operations.
>
> Yes. Functions with persistent state are generally a bad idea.
>
> Unfortunately, the "signal" module requires a callback parameter
> which is a plain function. So you have to send it a function,
> closure, or lambda.

Does it? The docs say that it just needs a callable object. An instance with a
__call__() method would suffice.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

From: Stephen Hansen on
On 2010-04-05 10:08:51 -0700, John Nagle said:
> Yes. Functions with persistent state are generally a bad idea.
>
> Unfortunately, the "signal" module requires a callback parameter
> which is a plain function. So you have to send it a function,
> closure, or lambda. Here, it's being sent a closure - "handler"
> bound to the state that existed when "signal.signal" was called.

Uhh, what?

>> class A:
.... def handle(self, foo, bar):
.... print "Okay"
....
>>> a = A()
>>> signal.signal(signal.SIGALRM, a.handle)
0
>>> Okay

Where after that call to signal.signal, I did kill -ALRM and such in
another process.

When Python says 'a function', it doesn't mean a -plain- function. A
method's a function too. Arguably, really, any callable is almost
always (as in I can't think of anywhere it doesn't) sufficient to be
Functiony enough to work.

--
--S

.... p.s: change the ".invalid" to ".com" in email address to reply privately.

From: Steven D'Aprano on
On Mon, 05 Apr 2010 10:08:51 -0700, John Nagle wrote:

> Alf P. Steinbach wrote:
>
>> Best is however to recognize that you have some state (your variable)
>> and some operations on that state (your callback), and that that is
>> what objects are all about. I.e. wrap your logic in a class. Then
>> 'lastModifiedTime' becomes an instance attribute, and 'handler' becomes
>> a method.
>>
>> It doesn't matter that there will only ever be one object (instance) of
>> that class.
>>
>> Classes were meant for just this sort of thing, state + operations.
>
> Yes. Functions with persistent state are generally a bad idea.


Persistent state is generally a bad idea, unless you need it. If you
think you need it, you probably don't. But if you do actually need
persistent state, it is better to hide it in some sort of routine
(perhaps a function, perhaps a callable instance, perhaps something else)
that can encapsulate the state, rather than store it in a global.



> Unfortunately, the "signal" module requires a callback parameter
> which is a plain function. So you have to send it a function, closure,
> or lambda. Here, it's being sent a closure - "handler" bound to the
> state that existed when "signal.signal" was called.


Help on built-in function signal in module signal:

signal(...)
signal(sig, action) -> action

Set the action for the given signal. The action can be SIG_DFL,
SIG_IGN, or a callable Python object. [...]


Doesn't seem like there is any requirement for it to be a regular
function. Anything callable with the right signature should work, and if
it doesn't, that's a bug.



--
Steven