简体   繁体   中英

Python Is there a way to use decorator wrap a function of class?

Finally I fix this ask use code like this:(2018-06-03)

class Main:
    @app.route('^/$')
    def default(self):
        return 'hello from class ccc'

module=sys.modules[func.__module__]
cls=getattr(module,func.__qualname__.replace('.'+func.__name__,''))      
ins=cls()
m=getattr(cls,func.__name__)    
resp.body=m(cls) #func.__module__+'.'+func.__qualname__+' func:'+func.__name__

That's not pyhonic right?I'm new guy to python

//////old

class D:
    def __init__(self):
        self.handlers={}

    def check(self,func):
        self.handlers['h']=func

        def decorator(*args,**kwargs):
            return func(*args,**kwargs)
        return decorator

    def call(self,p):
        return self.handlers['h'](p)

d=D()

class Test:
    @d.check
    def prt(self,v):
        print(v)

t=Test()
d.call(123)

There is error info:prt() missing 1 required positional argument: 'v'

It seems need a parameter named 'self' but how can i pass it?

//edit (2018-06-01)

Thanks to all.I ask this cause I try write a python web framework.And I want route to a method of class like below

app=MyFrm()

class Controller:
    @app.route('/')
    def hello():
        return 'hello world'

But existing do like below.It's no need or nobody to do this in python?

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

Now I fixed this problem use @staticmethod

Decorators are applied when the function is declared , so just before the class is created to which the functions are registered as methods.

So func passed into your decorator is not bound to an instance , and you can't just call it without explicitly passing in an instance. Moreover, you don't have access to the instance stored in t , that's created entirely outside of the decorator.

You'd have to explicitly pass along the instance to call the method on:

t = Test()
d.call(t, 123)

or register methods after creating an instance, in the __init__ method. Methods are bound when you look them up as an attribute on an instance, via the decriptor protocol . Only bound methods have a reference to the instance that is to be bound to self :

>>> class Foo:
...     def bar(self):
...         return self
...
>>> Foo.bar  # unbound
<function Foo.bar at 0x108d38f28>
>>> Foo.bar()  # no self to bind to
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bar() missing 1 required positional argument: 'self'
>>> instance = Foo()
>>> instance.bar  # bound method
<bound method Foo.bar of <__main__.Foo object at 0x109a916d8>>
>>> instance.bar.__self__ is instance  # to the instance
True
>>> instance.bar()  # so the instance is passed in for self
<__main__.Foo object at 0x109a916d8>
>>> Foo.bar(instance)  # or you can do it manually
<__main__.Foo object at 0x109a916d8>

If you do fix your registration to store bound methods, you'll need to take into account that the registration is now an extra reference to the instance, keeping it alive in memory even if all other references to the instance are removed. If this is an issue, you'd need to use weak references to the unbound function and the instance , not to the method, as methods are created dynamically and generally have no other references to them . See using python WeakSet to enable a callback functionality

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM