Code: Alles auswählen
def do_something(func):
magic_happens_here(func)
class MyClass(object):
@do_something
def method(self):
pass
@do_something
def function():
pass
Code: Alles auswählen
def do_something(func):
magic_happens_here(func)
class MyClass(object):
@do_something
def method(self):
pass
@do_something
def function():
pass
Code: Alles auswählen
import inspect
def do_something(func):
try:
print 'Class method' if inspect.stack(1)[2][4][0].strip().startswith('class') else ''
except IndexError:
print 'No class method'
return func
class MyClass(object):
@do_something
def method(self):
pass
@do_something
def function():
pass
Kann ich nicht so recht nachvollziehen, denn:Defnull hat geschrieben:Kein Unterschied.
Code: Alles auswählen
>>> from inspect import isfunction, ismethod
>>> def foo(): pass
...
>>> isfunction(foo)
True
>>> ismethod(foo)
False
>>> class Foo(object):
... def bar(self): pass
...
>>> foo = Foo()
>>> isfunction(foo.bar)
False
>>> ismethod(foo.bar)
True
Code: Alles auswählen
>>> import inspect
>>>
>>> def do_something(func):
... print inspect.ismethod(func), inspect.isfunction(func)
... return func
...
>>> class MyClass(object):
... @do_something
... def method(self):
... pass
...
False True
>>> @do_something
... def function():
... pass
...
False True
Für die zwei Möglichkeiten reicht im Prinzip auch ein Boolsnafu hat geschrieben:Wie wäre erstmal ein `@do_something(type='function')`, welches der Benutzer bei Bedarf auf `type='method'` stellt? Im Zuge von späteren Verbesserungen kann man da ja immer noch was dran machen. Bei dieser Stack-Lösung ist die Sache, dass es zum Einen hässlich ist und man zum Anderen ja nicht unbedingt wissen kann, ob das bei jeder Python-Version/-Implementierung so klappt.
Code: Alles auswählen
def deco(f):
def art(*args):
print("Ich dekoriere Funktion %s mit %d args" % (f, len(args)))
return f(*args)
art.f = f
return art
@deco
def f(n):
return n + 1
def method_deco(f):
def method_art(*args):
print("Ich dekoriere eine Methode %s mit %d args" % (f, len(args)))
return f(*args)
return method_art
class M(type):
def __init__(self, name, bases, dct):
super(M, self).__init__(name, bases, dct)
for k, v in dct.items():
if isinstance(v, type(deco)) and hasattr(v, "f"):
setattr(self, k, method_deco(v.f))
class B(metaclass=M):
pass
class C(B):
@deco
def m(self, n):
return n - 1
print(f(3))
print(C.m(C(), 4))
print(C().m(5))
Code: Alles auswählen
from bottle import route, BaseApp
class MyApp(BaseApp):
@route('/')
@route('/:name')
def index(self, name="World"):
return "Hello %s!" % name