How to get self into a Python method without explicitly accepting it

后端 未结 5 1008
失恋的感觉
失恋的感觉 2020-12-09 12:53

I\'m developing a documentation testing framework -- basically unit tests for PDFs. Tests are (decorated) methods of instances of classes defined by the framework, and these

5条回答
  •  误落风尘
    2020-12-09 13:12

    The trick is to add 'self' to f.func_globals. This works in python2.6. I really should get around to installing other versions to test stuff like this on. Sorry for the wall of code but I cover two cases: doing it with a metaclass and doing it with a decorator. For your usecase, I think the metaclass is better since the whole point of this exercise is to shield users from syntax.

    import new, functools
    
    class TestMeta(type):
        def __new__(meta, classname, bases, classdict):
            for item in classdict:
                if hasattr(classdict[item], '__call__'):
                    classdict[item] = wrap(classdict[item])
            return type.__new__(meta, classname, bases, classdict)
    
    def wrap(f):
        @functools.wraps(f)
        def wrapper(self):
            f.func_globals['self'] = self        
            return f()
        return wrapper
    
    def testdec(f):
        @functools.wraps(f)
        def wrapper():
            return f()
        return wrapper
    
    class Test(object):
        __metaclass__ = TestMeta
        message = 'You can do anything in python'
        def test():
            print self.message
    
        @testdec
        def test2():
            print self.message + ' but the wrapper funcion can\'t take a self argument either or you get a TypeError'
    
    class Test2(object):
        message = 'It also works as a decorator but (to me at least) feels better as a metaclass'
        @wrap
        def test():
            print self.message
    
    
    t = Test()
    t2 = Test2()
    t.test()
    t.test2()
    t2.test()
    

提交回复
热议问题