[RFC]参数多态性 [英] [RFC] Parametric Polymorphism
问题描述
很抱歉,如果之前已经讨论过这个问题,那就是我想念的那些
Python。我使用isinstance()来解决这个问题,但是它会更清晰
使用相同名称但不同参数的单独函数
类型。我认为这个想法非常接近Lisp / CLOS
方法的实现。
下面只是简单的实现示例(类函数是
不支持)但它可以进一步扩展/优化/修改
更好的类型检测,如issubclass()等。这个想法类似于
@accepts decorator:
methods = dict()
def方法(*类型):
def build_method(f):
断言len(类型)== f.func_code.co_argcount
如果不是方法中的f.func_name:
方法[ f.func_name] = dict()
方法[f.func_name] [str(types)] = f
def new_f(* args,** kwds):
type_str = str(元组(args中arg的[类型(arg)]))
方法中的断言type_str [f.func_name]
返回方法[f.func_name] [type_str](* args,** kwds)
new_f.func_name = f.func_name
返回new_f
返回build_method
及其利用率:
@method(int)
def test(arg):
print''int '',arg
@method(浮动)
def测试(arg):
打印''浮动'', arg
test(1)#success
test(1.5)#success
test(1,2)#assert失败
test(''aaa'')#assert失败
让我知道你的想法。谢谢。
-
Catalin
Hi,
Sorry if this was previously discussed but it''s something I miss in
Python. I get around this using isinstance() but it would be cleaner
to have separate functions with the same name but different argument
types. I think the idea gets quite close to the Lisp/CLOS
implementation of methods.
Below is just simple implementation example (and class functions are
not supported) but it can be further extended/optimised/modified for
better type detection like issubclass() etc. The idea is similar to
the @accepts decorator:
methods = dict()
def method(*types):
def build_method(f):
assert len(types) == f.func_code.co_argcount
if not f.func_name in methods:
methods[f.func_name] = dict()
methods[f.func_name][str(types)] = f
def new_f(*args, **kwds):
type_str = str(tuple([type(arg) for arg in args]))
assert type_str in methods[f.func_name]
return methods[f.func_name][type_str](*args, **kwds)
new_f.func_name = f.func_name
return new_f
return build_method
And its utilisation:
@method(int)
def test(arg):
print ''int'', arg
@method(float)
def test(arg):
print ''float'', arg
test(1) # succeeds
test(1.5) # succeeds
test(1, 2) # assert fails
test(''aaa'') # assert fails
Let me know what you think. Thanks.
--
Catalin
推荐答案
Catalin Marinas写道:
Catalin Marinas wrote:
很抱歉,如果之前已经讨论过这个问题,那就是我想念的Python。我使用isinstance()来解决这个问题,但是使用具有相同名称但不同参数类型的单独函数会更清晰。我认为这个想法非常接近Lisp / CLOS
方法的实现。
下面只是简单的实现示例(并且不支持类函数)但它可以是进一步扩展/优化/修改了更好的类型检测,如issubclass()等。这个想法类似于@accepts装饰器:
methods = dict()
def方法(*类型):
def build_method(f):
断言len(类型)== f.func_code.co_argcount
如果不是f。方法中的func_name:
方法[f.func_name] = dict()
方法[f.func_name] [str(types)] = f
def new_f(* args, ** kwds):
type_str = str(元组(args中的arg的[type(arg)]))
在方法[f.func_name]中断言type_str
返回方法[f.func_name ] [type_str](* args,** kwds)
new_f.func_name = f.func_name
返回new_f
返回build_metho d
及其利用率:
@method(int)
def test(arg):
print''int'',arg
@method(浮动)
def测试(arg):打印''漂浮'',arg
测试(1)#success
测试(1.5)#成功
测试(1,2)#assert失败
测试(''aaa'')#assert失败
让我知道你的想法。谢谢。
Hi,
Sorry if this was previously discussed but it''s something I miss in
Python. I get around this using isinstance() but it would be cleaner
to have separate functions with the same name but different argument
types. I think the idea gets quite close to the Lisp/CLOS
implementation of methods.
Below is just simple implementation example (and class functions are
not supported) but it can be further extended/optimised/modified for
better type detection like issubclass() etc. The idea is similar to
the @accepts decorator:
methods = dict()
def method(*types):
def build_method(f):
assert len(types) == f.func_code.co_argcount
if not f.func_name in methods:
methods[f.func_name] = dict()
methods[f.func_name][str(types)] = f
def new_f(*args, **kwds):
type_str = str(tuple([type(arg) for arg in args]))
assert type_str in methods[f.func_name]
return methods[f.func_name][type_str](*args, **kwds)
new_f.func_name = f.func_name
return new_f
return build_method
And its utilisation:
@method(int)
def test(arg):
print ''int'', arg
@method(float)
def test(arg):
print ''float'', arg
test(1) # succeeds
test(1.5) # succeeds
test(1, 2) # assert fails
test(''aaa'') # assert fails
Let me know what you think. Thanks.
谷歌搜索gnosis utils和multimethods以查看更多oldfashioned
实现。但是你的方法当然很有意思 - 但是,我需要这样的功能。通常鸭子打字很适合我。
问候,
Diez
google for gnosis utils and multimethods to see a more "oldfashioned"
implementation. But your approach certainly is interesting - however, I
_rarely_ need such functionality. Ususally duck-typing suits me well.
Regards,
Diez
Diez B. Roggisch <德*** @ nospam.web.de>写道:
"Diez B. Roggisch" <de***@nospam.web.de> wrote:
google for gnosis utils和multimethods看到一个更老式的实现。
我现在记得已经看过了,但需要大量输入才能实现它,你可以从一个人那里调用一个不同的函数名称。 />
你定义,降低代码清晰度。
但你的方法肯定很有趣 - 但是,
这个想法并不新鲜。 Lisp / CLOS实现defmethod宏,
创建一个通用函数(即调度程序),其名称与
您定义的函数相同:
http://www.lisp.org/HyperSpec/Body/mac_defmethod.html 一>。实际上,
defmehod宏是实现对象多态的基础。
我_rarely_需要这样的功能。通常鸭子打字适合我
好。
google for gnosis utils and multimethods to see a more "oldfashioned"
implementation.
I now remember to have seen it but it requires a lot of typing to
achieve it and you would call a different function name from the one
you define, reducing the code clarity.
But your approach certainly is interesting - however,
The idea is not new. Lisp/CLOS implements the defmethod macro which
creates a generic function (i.e. a dispatcher) with the same name as
the function you define:
http://www.lisp.org/HyperSpec/Body/mac_defmethod.html. Actually, the
defmehod macro is the base for implementing object polymorphism.
I _rarely_ need such functionality. Ususally duck-typing suits me
well.
当然,鸭子打字很简单,但是参数化的
多态性当类型不相关时很有用。让我们说你
想要实现一个彩色打印功能,它应该支持基本的
类型,如整数和浮点数以及列表和词典。在这个
的情况下,感谢功能装饰支持,代码将是
更清晰。
另一个用例是使用
函数扩展类的功能但是你不能轻易修改类或创建子类
(对象是由某个工厂生成的
第三方图书馆)。当然,你可以绕过这个
但参数多态可以减少编写的代码。
这个想法只需要一个优化的(和确定性的)实现
基于子类 - 超类
关系的最佳参数匹配。它还可以扩展为基于
参数值实现多态性(人们试图在C ++中使用
复杂模板做的事情,但是,仅在编译时,
明显的缺点)。
-
Catalin
Of course, duck-typing is simple to use but the parametric
polymorphism is useful when the types are unrelated. Let''s say you
want to implement a colour-print function which should support basic
types like ints and floats as well as lists and dictionaries. In this
case, and thank to the function decorations support, the code would be
clearer.
Another use case is to extended the functionality of a class using
functions but you cannot easily modify the class or create a subclass
(the objects are generated by some factory implemented in a
third-party library). Of course, you might be able to get around this
but parametric polymorphism could reduce the written code.
This idea only needs an optimised (and deterministic) implementation
for the best parameter match based on subclass-superclass
relations. It can also be extended to implement polymorphism based on
the parameter values (something people tried to do in C++ with
complicated templates but, well, only at compilation time, with
obvious drawbacks).
--
Catalin
Catalin Marinas写道:
Catalin Marinas wrote:
很抱歉,如果之前已经讨论过这个问题,那就是我想念的Python。我使用isinstance()来解决这个问题,但是使用具有相同名称但不同参数类型的单独函数会更清晰。我认为这个想法非常接近Lisp / CLOS
方法的实现。
Sorry if this was previously discussed but it''s something I miss in
Python. I get around this using isinstance() but it would be cleaner
to have separate functions with the same name but different argument
types. I think the idea gets quite close to the Lisp/CLOS
implementation of methods.
看看PJE的通用函数实现。 PyCon幻灯片
: http://www.python.org/pycon/2005/pap...Con05Talk.html 。
-
Benji York
Take a look at PJE''s generic function implementation. PyCon slides
here: http://www.python.org/pycon/2005/pap...Con05Talk.html.
--
Benji York
这篇关于[RFC]参数多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!