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


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 stdin, line 1, in module
 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 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 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 Arnaud Delobelle
Steven D'Aprano st...@remove-this-cybersource.com.au 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 st...@remove-this-cybersource.com.au 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 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__:
code from verify function

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