Decorator question

C

Chris

I have a class (A, for instance) that possesses a boolean (A.b, for
instance) that is liable to change over an instance's lifetime.

Many of the methods of this class (A.foo, for instance) should not
execute as long as this boolean is false, but should instead raise an
exception.

Can I use a decorator to implement this functionality? More exactly,
could I define a function called 'checker' that accomplishes this:

def checker(f):
...

class A():

b = True

@checker
def foo(self,...):
print 'in foo'

a = A()
a.foo()
a.b = False
a.foo()

would result in:

'in foo'
Exception: ...

This exact solution isn't necessary, just something that doesn't
require me to have the clunky:

def foo(self,...):
if self.b:
...
else: raise Exception('b attribute must be true before executing
this method')

in every method.

Thanks,

Chris
 
C

Chris

I have a class (A, for instance) that possesses a boolean (A.b, for
instance) that is liable to change over an instance's lifetime.

Many of the methods of this class (A.foo, for instance) should not
execute as long as this boolean is false, but should instead raise an
exception.

Can I use a decorator to implement this functionality?  More exactly,
could I define a function called 'checker' that accomplishes this:

def checker(f):
    ...

class A():

    b = True

    @checker
    def foo(self,...):
        print 'in foo'

a = A()
a.foo()
a.b = False
a.foo()

would result in:

'in foo'
Exception: ...

This exact solution isn't necessary, just something that doesn't
require me to have the clunky:

def foo(self,...):
    if self.b:
        ...
    else: raise Exception('b attribute must be true before executing
this method')

in every method.

Thanks,

Chris

Sorry, discovered answer here:

http://stackoverflow.com/questions/2309124/get-class-in-python-decorator
 
M

MRAB

I have a class (A, for instance) that possesses a boolean (A.b, for
instance) that is liable to change over an instance's lifetime.

Many of the methods of this class (A.foo, for instance) should not
execute as long as this boolean is false, but should instead raise an
exception.

Can I use a decorator to implement this functionality? More exactly,
could I define a function called 'checker' that accomplishes this:

def checker(f):
...

class A():

b = True

@checker
def foo(self,...):
print 'in foo'

a = A()
a.foo()
a.b = False
a.foo()

would result in:

'in foo'
Exception: ...

This exact solution isn't necessary, just something that doesn't
require me to have the clunky:

def foo(self,...):
if self.b:
...
else: raise Exception('b attribute must be true before executing
this method')

in every method.
How about this:

def checker(func):
def wrapper(self, *args, **kwargs):
if not self.b:
raise Exception('b attribute must be true before executing
this method')
return func(self, *args, **kwargs)
return wrapper
 
T

Thomas L. Shinnick

I have a class (A, for instance) that possesses a boolean (A.b, for
instance) that is liable to change over an instance's lifetime.

Many of the methods of this class (A.foo, for instance) should not
execute as long as this boolean is false, but should instead raise an
exception.

Can I use a decorator to implement this functionality? More exactly,
could I define a function called 'checker' that accomplishes this:

Mark Summerfield's book "Programming in Python 3" has an example
something like this (p.357) called 'positive_result'. I hesitate to
quote the entire thing, so I'll quote only the inner 'half' of the decorator:
def wrapper(*args, **kwargs):
result = function(*args, **kwargs)
assert result >= 0, function.__name__ + "() result isn't >= 0"
return result

I would guess you would have to count on the first item in the
methods' args to be self, and use that to test whether your attribute
is false/true?

Mark?
 
M

Mark Summerfield

Mark Summerfield's book "Programming in Python 3" has an example
something like this (p.357) called 'positive_result'.   I hesitate to
quote the entire thing, so I'll quote only the inner 'half' of the decorator:
         def wrapper(*args, **kwargs):
             result = function(*args, **kwargs)
             assert result >= 0, function.__name__ + "() result isn't >= 0"
             return result

I would guess you would have to count on the first item in the
methods' args to be self, and use that to test whether your attribute
is false/true?

Mark?

Here's a simple example that I think does what you're after:

##########################################

#!/usr/bin/env python3

import functools

def execute_if_valid(function):
@functools.wraps(function)
def wrapper(*args, **kwargs):
if not args[0].valid:
raise Exception("invalid instance")
return function(*args, **kwargs)
return wrapper

class A:
valid = True

def foo(self):
print("called foo() on a valid or invalid instance")

@execute_if_valid
def bar(self):
print("called bar() on a valid instance")

a = A()
a.foo()
a.bar()
a.valid = False
a.foo()
a.bar()

##########################################

Here's its output:

##########################################
called foo() on a valid or invalid instance
called bar() on a valid instance
called foo() on a valid or invalid instance
Traceback (most recent call last):
File "./test.py", line 32, in <module>
a.bar()
File "./test.py", line 10, in wrapper
raise Exception("invalid instance")
Exception: invalid instance
##########################################
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top