You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Python 3.4 added the ``singledispatch`` decorator to the ``functools`` standard library module.
6
-
This library extends this functionality to instance methods (and works for functions too).
7
6
8
-
To define a generic method , decorate it with the ``@singledispatch`` decorator. Note that the dispatch happens on the type of the first argument, create your function accordingly.
7
+
Python 3.4 added the ``singledispatch`` decorator to the ``functools``
8
+
standard library module. This library extends this functionality to
9
+
instance methods (and works for functions too).
10
+
11
+
To define a generic method , decorate it with the ``@singledispatch``
12
+
decorator. Note that the dispatch happens on the type of the first
13
+
argument, create your function accordingly.
14
+
15
+
::
9
16
10
17
>>> from methoddispatch import singledispatch, register, SingleDispatch
11
18
@@ -15,7 +22,10 @@ To define a generic method , decorate it with the ``@singledispatch`` decorator.
15
22
... print("Let me just say,", end=" ")
16
23
... print(arg)
17
24
18
-
To add overloaded implementations to the function, use the ``register()`` attribute of the generic function. It is a decorator, taking a type parameter and decorating a function implementing the operation for that type
25
+
To add overloaded implementations to the function, use the
26
+
``register()`` attribute of the generic function. It is a decorator,
27
+
taking a type parameter and decorating a function implementing the
28
+
operation for that type::
19
29
20
30
>>> @fun.register(int)
21
31
... def _(arg, verbose=False):
@@ -30,15 +40,18 @@ To add overloaded implementations to the function, use the ``register()`` attrib
30
40
... for i, elem in enumerate(arg):
31
41
... print(i, elem)
32
42
33
-
To enable registering lambdas and pre-existing functions, the ``register()`` attribute can be used in a functional form::
43
+
To enable registering lambdas and pre-existing functions, the
44
+
``register()`` attribute can be used in a functional form::
34
45
35
46
>>> def nothing(arg, verbose=False):
36
47
... print("Nothing.")
37
48
...
38
49
>>> fun.register(type(None), nothing)
39
50
<function nothing at 0x03D3FDB0>
40
51
41
-
The ``register()`` attribute returns the undecorated function which enables decorator stacking, pickling, as well as creating unit tests for each variant independently
52
+
The ``register()`` attribute returns the undecorated function which
53
+
enables decorator stacking, pickling, as well as creating unit tests for
54
+
each variant independently::
42
55
43
56
>>> from decimal import Decimal
44
57
>>> @fun.register(float)
@@ -51,7 +64,8 @@ The ``register()`` attribute returns the undecorated function which enables deco
51
64
>>> fun_num is fun
52
65
False
53
66
54
-
When called, the generic function dispatches on the type of the first argument::
67
+
When called, the generic function dispatches on the type of the first
68
+
argument::
55
69
56
70
>>> fun("Hello, world.")
57
71
Hello, world.
@@ -70,16 +84,22 @@ When called, the generic function dispatches on the type of the first argument::
70
84
>>> fun(1.23)
71
85
0.615
72
86
73
-
Where there is no registered implementation for a specific type, its method resolution order is used to find a more generic implementation. The original function decorated with ``@singledispatch`` is registered for the base ``object`` type, which means it is used if no better implementation is found.
87
+
Where there is no registered implementation for a specific type, its
88
+
method resolution order is used to find a more generic implementation.
89
+
The original function decorated with ``@singledispatch`` is registered
90
+
for the base ``object`` type, which means it is used if no better
91
+
implementation is found.
74
92
75
-
To check which implementation will the generic function choose for a given type, use the ``dispatch()`` attribute::
93
+
To check which implementation will the generic function choose for a
@@ -90,7 +110,8 @@ To access all registered implementations, use the read-only ``registry`` attribu
90
110
>>> fun.registry[object]
91
111
<function fun at 0x103fe0000>
92
112
93
-
Decorating class methods requires the class to inherit from ``SingleDispatch``
113
+
Decorating class methods requires the class to inherit from
114
+
``SingleDispatch``::
94
115
95
116
>>> class BaseClass(SingleDispatch):
96
117
... @singledispatch
@@ -107,8 +128,12 @@ Decorating class methods requires the class to inherit from ``SingleDispatch``
107
128
>>> b.foo(1)
108
129
'int'
109
130
110
-
Subclasses can extend the type registry of the function on the base class with their own overrides.
111
-
Because we do not want to modify the base class ``foo`` registry the ``methoddispatch.register`` decorator must be used instead of ``foo.register``. The module level ``register`` function takes either the method name or the method itself as the first parameter and the dispatch type as the second.
131
+
Subclasses can extend the type registry of the function on the base
132
+
class with their own overrides. Because we do not want to modify the
133
+
base class ``foo`` registry the ``methoddispatch.register`` decorator
134
+
must be used instead of ``foo.register``. The module level ``register``
135
+
function takes either the method name or the method itself as the first
136
+
parameter and the dispatch type as the second.::
112
137
113
138
>>> class SubClass(BaseClass):
114
139
... @register('foo', float)
@@ -125,13 +150,15 @@ Because we do not want to modify the base class ``foo`` registry the ``methoddis
125
150
>>> s.foo(1.0)
126
151
'float'
127
152
128
-
The ``SingleDispatch`` mixin class ensures that each subclass has it's own independant copy of the dispatch registry
153
+
The ``SingleDispatch`` mixin class ensures that each subclass has it’s
154
+
own independant copy of the dispatch registry::
129
155
130
156
>>> b = BaseClass()
131
157
>>> b.foo(1.0)
132
158
'default'
133
159
134
-
Method overrides do not need to provide the ``register`` decorator again to be used in the dispatch of ``foo``
160
+
Method overrides do not need to provide the ``register`` decorator again
161
+
to be used in the dispatch of ``foo``::
135
162
136
163
>>> class SubClass2(BaseClass):
137
164
... def foo_int(self, bar):
@@ -141,10 +168,14 @@ Method overrides do not need to provide the ``register`` decorator again to be u
141
168
>>> s.foo(1)
142
169
'my int'
143
170
144
-
However, providing the register decorator with the same type will also work.
145
-
Decorating a method override with a different type (not a good idea) will register the different type and leave the base-class handler in place for the orginal type.
171
+
However, providing the register decorator with the same type will also
172
+
work. Decorating a method override with a different type (not a good
173
+
idea) will register the different type and leave the base-class handler
174
+
in place for the orginal type.
146
175
147
-
In Python 3.6 and later, for functions annotated with types, the decorator will infer the type of the first argument automatically as shown below
176
+
In Python 3.6 and later, for functions annotated with types, the
177
+
decorator will infer the type of the first argument automatically as
178
+
shown below::
148
179
149
180
>>> class BaseClassAnno(SingleDispatch):
150
181
... @singledispatch
@@ -160,12 +191,19 @@ In Python 3.6 and later, for functions annotated with types, the decorator will
160
191
... def foo_float(self, bar: float):
161
192
... return 'float'
162
193
163
-
In Python 3.6 and earlier, the ``SingleDispatch`` class uses a meta-class ``SingleDispatchMeta`` to manage the dispatch registries. However in Python 3.6 and later the ``__init_subclass__`` method is used instead.
164
-
If your class also inherits from an ABC interface you can use the ``SingleDispatchABCMeta`` metaclass in Python 3.6 and earlier.
194
+
In Python 3.6 and earlier, the ``SingleDispatch`` class uses a
195
+
meta-class ``SingleDispatchMeta`` to manage the dispatch registries.
196
+
However in Python 3.6 and later the ``__init_subclass__`` method is used
197
+
instead. If your class also inherits from an ABC interface you can use
198
+
the ``SingleDispatchABCMeta`` metaclass in Python 3.6 and earlier.
165
199
166
-
Finally, accessing the method ``foo`` via a class will use the dispatch registry for that class
200
+
Finally, accessing the method ``foo`` via a class will use the dispatch
0 commit comments