Re: Optimizing methods away or not?

2008-12-14 Thread Terry Reedy

Steven D'Aprano wrote:
I have a class with a method meant to verify internal program logic (not 
data supplied by the caller). Because it is time-consuming but optional, 
I treat it as a complex assertion statement, and optimize it away if 
__debug__ is false:


class Parrot:
def __init__(self, *args):
print "Initialising instance..."
if __debug__:
self.verify()  # check internal program state, not args
if __debug__:
def verify(self):
print "Verifying..."


Given that verify is only called from within _init__, I would put 
everything within one 'if __debug__' statement.  Either inline


if __debug__:


or if for some reason you really don't like that, nested

if __debug__:
   def verify():
  print "Verifying..."
   verify()

tjr

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


Re: Optimizing methods away or not?

2008-12-14 Thread Arnaud Delobelle
Steven D'Aprano  writes:

> On Sun, 14 Dec 2008 10:52:25 +, Arnaud Delobelle wrote:
>
>> You could also not use the metaclass and use post_verify as a decorator
>
> Except that self.verify doesn't exist if __debug__ is false.

OK I wrote this as an afterthought.  I'm, sure it's not beyond your ability
to add

if not __debug__:
return method

at the start of the post_verify function :)

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


Re: Optimizing methods away or not?

2008-12-14 Thread Steven D'Aprano
On Sun, 14 Dec 2008 10:52:25 +, Arnaud Delobelle wrote:

> You could also not use the metaclass and use post_verify as a decorator

Except that self.verify doesn't exist if __debug__ is false.


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


Re: Optimizing methods away or not?

2008-12-14 Thread Arnaud Delobelle
Steven D'Aprano  writes:

> I have a class with a method meant to verify internal program logic (not 
> data supplied by the caller). Because it is time-consuming but optional, 
> I treat it as a complex assertion statement, and optimize it away if 
> __debug__ is false:
>
> class Parrot:
> def __init__(self, *args):
> print "Initialising instance..."
> if __debug__:
> self.verify()  # check internal program state, not args
> if __debug__:
> def verify(self):
> print "Verifying..."
>
>
> If I run Python normally, I can do this:

FWIW here is a way with a metaclass:

= verify_init.py =

from functools import wraps

def post_verify(method):
@wraps(method)
def decorated(self, *args):
result = method(self, *args)
self.verify()
return result
return decorated

class VerifyInit(type):
def __new__(meta, name, bases, attrs):
if __debug__:
attrs['__init__'] = post_verify(attrs['__init__'])
else:
del attrs['verify']
return type.__new__(meta, name, bases, attrs)

class Parrot:
 __metaclass__ = VerifyInit
 def __init__(self, *args):
 print "Initialising instance..."
 def verify(self):
 print "Verifying..."

coco = Parrot()

==

marigold:junk arno$ python verify_init.py 
Initialising instance...
Verifying...
marigold:junk arno$ python -O verify_init.py 
Initialising instance...

You could also not use the metaclass and use post_verify as a decorator:

class Parrot:
 @post_verify
 def __init__(self, *args):
 print "Initialising instance..."
 if __debug__:
 def verify(self):
 print "Verifying..."

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


Re: Optimizing methods away or not?

2008-12-14 Thread Steven D'Aprano
On Sun, 14 Dec 2008 09:19:45 +, Marc 'BlackJack' Rintsch wrote:

> On Sun, 14 Dec 2008 07:41:55 +, Steven D'Aprano wrote:
> 
>> I have a class with a method meant to verify internal program logic
>> (not data supplied by the caller). Because it is time-consuming but
>> optional, I treat it as a complex assertion statement, and optimize it
>> away if __debug__ is false:
...
>> What do others
>> think? Which do you consider better design?
> 
> None of it.  Why not simply:
> 
> class Parrot:
> def __init__(self, *args):
> print "Initialising instance..."
> assert self._verify()
> 
> def _verify(self):
> print "Verifying..."
> return None

For your method to work, I'd have to have _verify return a boolean flag 
instead of None, because assert None always fails.


> If you compile with -O the ``assert`` is optimized away.  But you still
> can call `_verify()` at specific points even in optimized code if you
> want or need.

That's a reasonable approach, if my use-case was for the caller to call 
the verify method. It's not: it's verifying my program logic rather than 
the caller's data, and it's only meaningful to do that verification at 
initialisation time.



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


Re: Optimizing methods away or not?

2008-12-14 Thread Marc 'BlackJack' Rintsch
On Sun, 14 Dec 2008 09:19:45 +, Marc 'BlackJack' Rintsch wrote:

> class Parrot:
> def __init__(self, *args):
> print "Initialising instance..."
> assert self.verify()

Here I meant ``assert self._verify()`` of course.

> def _verify(self):
> print "Verifying..."
> return None

Ciao,
Marc 'BlackJack' Rintsch
--
http://mail.python.org/mailman/listinfo/python-list


Re: Optimizing methods away or not?

2008-12-14 Thread Marc 'BlackJack' Rintsch
On Sun, 14 Dec 2008 07:41:55 +, Steven D'Aprano wrote:

> I have a class with a method meant to verify internal program logic (not
> data supplied by the caller). Because it is time-consuming but optional,
> I treat it as a complex assertion statement, and optimize it away if
> __debug__ is false:
> 
> class Parrot:
> def __init__(self, *args):
> print "Initialising instance..."
> if __debug__:
> self.verify()  # check internal program state, not args
> if __debug__:
> def verify(self):
> print "Verifying..."
> 
> 
> If I run Python normally, I can do this:
> 
 p = Parrot()
> Initialising instance...
> Verifying...
 p.verify()
> Verifying...
> 
> 
> and if I run Python with the -O flag, I get this:
> 
 p = Parrot()
> Initialising instance...
 p.verify()
> Traceback (most recent call last):
>   File "", line 1, in 
> AttributeError: Parrot instance has no attribute 'verify'
> 
> 
> This is the behaviour I want, but I haven't seen it before in other
> code. What do people think? Is it a good idea or a bad?
> 
> If you think it is a bad idea to have verify disappear under
> optimization, would you change your mind if it were called __verify
> instead?
> 
> 
> One possible alternative is to do something like this:
> 
> class Parrot:
> def __init__(self, *args):
> print "Initialising instance..."
> if __debug__:
> self.verify()
> def verify(self):
> if __debug__:
> print "Verifying..."
> return None
> # this is optional
> else:
> warnings.warn("verify() is a null op")
> 
> 
> which now means that Parrot instances will always have a verify method,
> even if it does nothing. I'm not sure I like that. What do others think?
> Which do you consider better design?

None of it.  Why not simply:

class Parrot:
def __init__(self, *args):
print "Initialising instance..."
assert self.verify()

def _verify(self):
print "Verifying..."
return None

If you compile with -O the ``assert`` is optimized away.  But you still 
can call `_verify()` at specific points even in optimized code if you 
want or need.

Ciao,
Marc 'BlackJack' Rintsch
--
http://mail.python.org/mailman/listinfo/python-list


Re: Optimizing methods away or not?

2008-12-14 Thread James Stroud

Steven D'Aprano wrote:

class Parrot:
def __init__(self, *args):
print "Initialising instance..."
if __debug__:
self.verify()  # check internal program state, not args
if __debug__:
def verify(self):
print "Verifying..."


+1 It looks good to me and the intent is much clearer than the other.
--
http://mail.python.org/mailman/listinfo/python-list


Optimizing methods away or not?

2008-12-13 Thread Steven D'Aprano
I have a class with a method meant to verify internal program logic (not 
data supplied by the caller). Because it is time-consuming but optional, 
I treat it as a complex assertion statement, and optimize it away if 
__debug__ is false:

class Parrot:
def __init__(self, *args):
print "Initialising instance..."
if __debug__:
self.verify()  # check internal program state, not args
if __debug__:
def verify(self):
print "Verifying..."


If I run Python normally, I can do this:

>>> p = Parrot()
Initialising instance...
Verifying...
>>> p.verify()
Verifying...


and if I run Python with the -O flag, I get this:

>>> p = Parrot()
Initialising instance...
>>> p.verify()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: Parrot instance has no attribute 'verify'


This is the behaviour I want, but I haven't seen it before in other code. 
What do people think? Is it a good idea or a bad?

If you think it is a bad idea to have verify disappear under 
optimization, would you change your mind if it were called __verify 
instead?


One possible alternative is to do something like this:

class Parrot:
def __init__(self, *args):
print "Initialising instance..."
if __debug__:
self.verify()
def verify(self):
if __debug__:
print "Verifying..."
return None
# this is optional
else:
warnings.warn("verify() is a null op")


which now means that Parrot instances will always have a verify method, 
even if it does nothing. I'm not sure I like that. What do others think? 
Which do you consider better design?



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