We can rename class methods at class definition time with a metaclass. This question is not about that.
This is more of a thought experiment, so humour me a little please.
Say I wanted to write two decorators that are used like this:
class SomeClass(object):
@append_A
def some_method( self ):
pass
@append_B
def some_method( self ):
pass
Which would result in SomeClass
having two methods: some_method_A
and some_method_B
Is this possible and if so, can you point me in the right direction?
I've tried changing the frame's f_locals
a few different ways, but the method name still persists.
No, it's not possible to change method names using decorator, as explained in the documentation:
The decorator syntax is merely syntactic sugar, the following two function definitions are semantically equivalent:
def f(...):
...
f = staticmethod(f)
@staticmethod
def f(...):
...
More syntax discussion goes here.
Update
I guess we could do something like leave the method alone in the decorator but also add a new method with an edited name in the scope it was defined (this case the class). The main thing is defining two methods with the same name then ending up with two differently named methods which are passed to the metaclass.
For this purpose you can use the class decorator:
def append_B(func):
func.suffix='_B'
return func
def appendable(class_obj):
for name in dir(class_obj):
if not name.startswith('_'):
attr = class_obj.__dict__[name] #getattr(class_obj, name)
suffix = getattr(attr, 'suffix', None)
if isinstance(suffix,str):
attr.suffix = None
setattr(class_obj,name+suffix, getattr(class_obj, name))
#delattr(class_obj,name)
return class_obj
The following usage allows you to define two names for the same method:
@appendable
class B(object):
@append_B
def some_method(s):
print 'B.some_method'
b=B()
b.some_method()
b.some_method_B()