Decorators using instance variables

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • robert2821

    Decorators using instance variables


    Hi,

    I'm new; greetings all!

    I'm wondering if the following program should work. I think it should
    print 'Hello, World', but instead it produces a TypeError. Is this a
    bug in decorators, a feature of them, or a mistake or misunderstandin g
    on my part?

    TIA, Bob


    def getdec (f):
    dec = decorator (f)
    return dec. docall

    class decorator:

    def __init__ (self, f):
    self. f = f

    def docall (self, *a):
    return self. f (*a)

    class test:
    @ getdec
    def doit (self, message):
    print message

    if __name__ == '__main__':
    foo = test ()
    foo. doit ('Hello, world')




  • castironpi

    #2
    Re: Decorators using instance variables

    On Aug 21, 9:22 pm, robert2821 <robert2...@ver izon.netwrote:
    Hi,
    >
    I'm new; greetings all!
    >
    I'm wondering if the following program should work.  I think it should
    print 'Hello, World', but instead it produces a TypeError.  Is this a
    bug in decorators, a feature of them, or a mistake or misunderstandin g
    on my part?
    >
    TIA,  Bob
    >
    def    getdec (f):
        dec = decorator (f)
        return dec. docall
    >
    class    decorator:
    >
        def __init__ (self, f):
            self. f = f
    >
        def docall (self, *a):
            return self. f (*a)
    >
    class    test:
        @ getdec
        def doit (self, message):
            print message
    >
    if __name__ == '__main__':
        foo = test ()
        foo. doit ('Hello, world')
    >
     Dec.py
    < 1KViewDownload
    Have a look at this and fiddle with it:

    from types import MethodType
    class decorator(objec t):

    def __init__ (self, f):
    self. f = f

    def docall (self, *a):
    print a
    return self. f (*a)

    def __get__( self, instance, owner ):
    print 'in __get__', instance, owner
    if instance is not None:
    return MethodType( self.docall, instance )
    return self.f

    class test:
    @ decorator
    def doit (self, message):
    print message

    if __name__ == '__main__':
    foo = test ()
    print test.doit
    print foo.doit
    foo. doit ('Hello, world')

    Output:

    in __get__ None __main__.test
    <function doit at 0x00A01170>
    in __get__ <__main__.tes t instance at 0x009FEE18__mai n__.test
    <bound method ?.docall of <__main__.tes t instance at 0x009FEE18>>
    in __get__ <__main__.tes t instance at 0x009FEE18__mai n__.test
    (<__main__.tes t instance at 0x009FEE18>, 'Hello, world')
    Hello, world

    The reason is that in the first version, the type of test.doit is
    InstanceType, and Python only 'binds' objects of type FunctionType to
    MethodType. MethodType is the type that contains an implicit first
    'self' parameter. If 'doit' has a __get__ attribute, it is called
    whenever -class-.doit or -instance-.doit are accessed, and it returns
    a bound method, or something else it likes.

    A little more investigating reveals:
    >>def f(): pass
    ...
    >>dir( f )
    ['__call__', '__class__', '__delattr__', '__dict__', '__doc__',
    '__get__', '__ge
    tattribute__', '__hash__', '__init__', '__module__', '__name__',
    '__new__', '__r
    ...

    functions have a '__get__' attribute to perform this very thing.

    Comment

    Working...