Re: Optimizing methods away or not?
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?
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?
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?
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?
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?
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?
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?
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