【发布时间】:2011-08-25 22:41:02
【问题描述】:
受 What are good uses for Python3's "Function Annotations" 中的 Muhammad Alkarouri 回答的启发,我想为方法而不是常规函数执行此 multimethod。但是,当我这样做时
registry = {}
class MultiMethod(object):
def __init__(self, name):
self.name = name
self.typemap = {}
def __call__(self, *args):
types = tuple(arg.__class__ for arg in args) # a generator expression!
function = self.typemap.get(types)
if function is None:
raise TypeError("no match")
return function(*args)
def register(self, types, function):
if types in self.typemap:
raise TypeError("duplicate registration")
self.typemap[types] = function
def multimethod(function):
name = function.__name__
mm = registry.get(name)
if mm is None:
mm = registry[name] = MultiMethod(name)
types = tuple(function.__annotations__.values())
mm.register(types, function)
return mm
class A:
@multimethod
def foo(self, a: int):
return "an int"
a = A()
print( a.foo( 1 ) )
我知道了:
Traceback (most recent call last):
File "test.py", line 33, in <module>
print( a.foo( 1 ) )
File "test.py", line 12, in __call__
return function(*args)
TypeError: foo() takes exactly 2 arguments (1 given)
这似乎是意料之中的,正如 Decorating a method 中所解释的那样,因为 self 参数。
但我不知道如何使它工作。好吧,当我删除“自我”时,它(几乎)工作正常,但我不想删除它。请注意,我这样做是为了练习,我知道有一些库提供方法重载。
我尝试了什么:
很傻,但想试试 - 在
def multimethod( function )中添加参数self- 同样的错误我曾考虑在
class MultiMethod的__init__中添加第三个参数-obj并将self存储为成员,但我无法通过multimethod执行此操作,因为它是一个函数.我不想为装饰器添加参数,因此忽略此选项(如果可能的话)
我阅读了几个类似的问题,但没有找到我想要的。我很确定这是一个愚蠢的问题,但我没有想法。
【问题讨论】:
标签: python methods python-3.x decorator