Optimizing methods away or not?

Arnaud Delobelle arnodel at googlemail.com
Sun Dec 14 05:52:25 EST 2008


Steven D'Aprano <steve at 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



More information about the Python-list mailing list