我正忙于创建一个元类,用一个具有正确实现的新类替换类上的存根函数。原始功能可以使用任何签名。我的问题是我无法弄清楚如何使用与旧签名相同的签名创建新功能。我该怎么做?
更新
这与“我如何使用与另一个函数具有相同签名的动态创建函数?”的实际问题无关,但我添加此内容以说明为什么我可以'使用子类。
我正在尝试在Python中实现类似Scala Case Classes的内容。 (不是模式匹配方面只是自动生成的属性,eq,hash和str方法。)
我想要这样的事情:
>>> class MyCaseClass():
... __metaclass__ = CaseMetaClass
... def __init__(self, a, b):
... pass
>>> instance = MyCaseClass(1, 'x')
>>> instance.a
1
>>> instance.b
'x'
>>> str(instance)
MyCaseClass(1, 'x')
据我所见,没有办法用子类。
答案 0 :(得分:3)
我相信functools.wraps
不会重现原始呼叫签名。但是,Michele Simionato的decorator module确实:
import decorator
class FooType(type):
def __init__(cls,name,bases,clsdict):
@decorator.decorator
def modify_stub(func, *args,**kw):
return func(*args,**kw)+' + new'
setattr(cls,'stub',modify_stub(clsdict['stub']))
class Foo(object):
__metaclass__=FooType
def stub(self,a,b,c):
return 'original'
foo=Foo()
help(foo.stub)
# Help on method stub in module __main__:
# stub(self, a, b, c) method of __main__.Foo instance
print(foo.stub(1,2,3))
# original + new
答案 1 :(得分:0)
可能使用inspect.getargspecs
执行此操作。甚至还有一个PEP in place可以让它变得更容易。
但是 - 这不是一件好事。你能想象一下,在运行时动态创建你的函数会有多少调试/维护噩梦 - 不仅仅是这样,而是由元类完成的?我不明白你为什么要动态替换存根;你想改变这个功能,你不能只改变代码吗?我的意思是,假设你有一个班级
class Spam( object ):
def ham( self, a, b ):
return NotImplemented
由于您不知道它的意图,因此元类实际上无法实现任何功能。如果您知道ham
的意图,可以在ham
或其中一个父类中执行此操作,而不是返回NotImplemented
。
答案 2 :(得分:0)
使用functools.wraps
>>> from functools import wraps
>>> def f(a,b):
return a+b
>>> @wraps(f)
def f2(*args):
print(args)
return f(*args)
>>> f2(2,5)
(2, 5)
7