Python 3.4 增加了使用静态方法定义函数重载的功能.这基本上是文档中的示例:
from functools import singledispatch
class TestClass(object):
@singledispatch
def test_method(arg, verbose=False):
if verbose:
print("Let me just say,", end=" ")
print(arg)
@test_method.register(int)
def _(arg):
print("Strength in numbers, eh?", end=" ")
print(arg)
@test_method.register(list)
def _(arg):
print("Enumerate this:")
for i, elem in enumerate(arg):
print(i, elem)
if __name__ == '__main__':
TestClass.test_method(55555)
TestClass.test_method([33, 22, 11])
Run Code Online (Sandbox Code Playgroud)
在其最纯粹的形式中,singledispatch实现依赖于第一个用于标识类型的参数,因此将此功能扩展到实例方法变得棘手.
有没有人有任何关于如何使用(或jerry-rig)此功能以使其与实例方法一起使用的建议?
python single-dispatch instance-method python-3.x python-3.4
我正在努力理解单个和多个调度是什么.
我刚刚读到这个:http:
//en.wikipedia.org/wiki/Multiple_dispatch
从这个定义来看,我认为C#和VB.Net是多分派的,即使在编译时选择要调用的重载也是如此.
我在这里是正确的,还是我错过了什么?谢谢!
我在一本书中读到"你不能用julia创造传统'课程',采用单调度方式,比如obj.myfunc()"......我认为听起来更像是挑战而不是事实.
所以这是我的JavaClass公共/私人领域和方法的类型,仅仅是为了在朱莉娅有一些像丑陋这样丑陋的冲击和恐怖因素,在开发人员为避免它而烦恼之后:
type JavaClass
# Public fields
name::String
# Public methods
getName::Function
setName::Function
getX::Function
getY::Function
setX::Function
setY::Function
# Primary Constructor - "through Whom all things were made."
function JavaClass(namearg::String, xarg::Int64, yarg::Int64)
# Private fields - implemented as "closed" variables
x = xarg
y = yarg
# Private methods used for "overloading"
setY(yarg::Int64) = (y = yarg; return nothing)
setY(yarg::Float64) = (y = Int64(yarg * 1000); return nothing)
# Construct object
this = new()
this.name = namearg …Run Code Online (Sandbox Code Playgroud) 它是否与重载相同,如果没有,你可以在C#中提供每个例子吗?
我已经阅读了对SO中提出的类似问题的回复......我不理解发布给它的回复.
类似的问题在这里问
编辑:使用C#4.0中新的"动态"关键字...这会使语言"多调度"启用吗?
有没有办法“取消注册”泛型的注册函数?
例如:
from functools import singledispatch
@singledispatch
def foo(x):
return 'default function'
foo.register(int, lambda x: 'function for int')
# later I would like to revert this.
foo.unregister(int) # does not exist - this is the functionality I am after
Run Code Online (Sandbox Code Playgroud) 我正在重构一个将各种日期格式(即 ISO 8601 字符串、 、 等)转换datetime.date为datetime.datetimeUnix 时间戳的函数。
我希望使用新函数@singledispatch而不是类型检查,但我不知道如何保留前一个函数的类型提示:
import datetime\nfrom typing import Union\n\n\nMyDateTimeType = Union[int, str, datetime.datetime, datetime.date, None]\n\n\n# How do I retain this functionality with @singledispatch?\n# \xe2\xac\x87\xef\xb8\x8f\xe2\xac\x87\xef\xb8\x8f\xe2\xac\x87\xef\xb8\x8f\xe2\xac\x87\xef\xb8\x8f\xe2\xac\x87\xef\xb8\x8f\xe2\xac\x87\xef\xb8\x8f\xe2\xac\x87\xef\xb8\x8f\ndef to_unix_ts(date: MyDateTimeType = None) -> Union[int, None]:\n """Convert various date formats to Unix timestamp..."""\n if type(date) is int or date is None:\n return date\n\n if type(date) is str:\n # Handle string argument...\n\n elif type(date) is datetime.datetime:\n # Handle datetime argument...\n\n elif type(date) …Run Code Online (Sandbox Code Playgroud) 当类型推断出现问题时(::Any在@code_warntype打印输出中),我的理解是函数调用是动态调度的。换句话说,在运行时,将检查参数的类型以查找MethodInstance具体参数类型的特化 ( )。需要在运行时而不是编译时执行此操作会产生性能成本。
(编辑:最初,我在类型检查和专业化查找之间说“多重分派找到合适的方法”,但我实际上不知道这部分是否在运行时发生。似乎只有在没有有效的情况下才需要发生专业化是存在的,需要进行编译。)
在只需要检查一个参数的具体类型的情况下,是否可以进行更快的动态单分派,就像在某种专业化查找表中一样?我只是找不到一种访问和调用MethodInstances 的方法,就好像它们是函数一样。
当谈到改变调度或专业化时,我想到了invoke和@nospecialize。invoke看起来它可能会直接跳到指定的方法,但检查多个参数类型和专业化仍然必须进行。@nospecialize不会跳过调度过程的任何部分,只会导致不同的专业化。
编辑:一个带有注释的最小示例,希望能够描述我正在谈论的内容。
struct Foo end
struct Bar end
# want to dispatch only on 1st argument
# still want to specialize on 2nd argument
baz(::Foo, ::Integer) = 1
baz(::Foo, ::AbstractFloat) = 1.0
baz(::Bar, ::Integer) = 1im
baz(::Bar, ::AbstractFloat) = 1.0im
x = Any[Foo(), Bar(), Foo()]
# run test1(x, 1) or test1(x, 1.0)
function test1(x, second)
# first::Any in …Run Code Online (Sandbox Code Playgroud) I would like to use functools.singledispatchmethod to overload the binary arithmetic operator methods of a class called Polynomial. The problem I have is that I can't find a way to register method calls where other is a Polynomial.
Perhaps better explained with a simple example:
from __future__ import annotations
from functools import singledispatchmethod
class Polynomial:
@singledispatchmethod
def __add__(self, other):
return NotImplemented
@__add__.register
def _(self, other: Polynomial):
return NotImplemented
Run Code Online (Sandbox Code Playgroud)
The code above raises a NameError:
NameError: name 'Polynomial' is …Run Code Online (Sandbox Code Playgroud) 我想根据传递给“调度”函数(例如使用)的参数的数据类型来调度 Python 函数(例如使用dict 方法isinstance())。是否有实施替代方案?最简单的方法是什么?
python ×5
c# ×2
julia ×2
dynamic ×1
functools ×1
oop ×1
python-2.7 ×1
python-3.4 ×1
python-3.x ×1
type-hinting ×1