http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/572161
It is much cleaner that the similar decorator I have previously written for Python 2.x, the used Python 3000 function annotations make it better for the following reasons:
1. The signature-related piece of syntax is right there where it belongs - next to the parameter. Where I used to write
@takes(int, str)I now write
@returns(bool)
def foo(i, s):
...
@typecheck2. I don't have to add checking to all the parameters simply because there was no way to skip one. Where it was
def foo(i: int, s: str) -> bool:
...
class Foo(object):it is now
@takes("Foo", str)
def foo(self, s):
...
class Foo:3. It plays nicely with the default values. This one has no equivalent in 2.x version, but it is nice to have:
@typecheck
def foo(self, s: str):
...
@typecheckOther than that, it is just a nice usable piece of code, extensible too. Here is a few more examples:
def foo(x: int = 10): # 10 is also checked
...
@typecheck
def foo(*, k: optional(str) = None):
...
@typecheck
def foo(x: with_attr("write", "flush")):
...
@typecheck
def foo(*, k: by_regex("^[0-9]+$")):
...
@typecheck
def swap_tuple(x: (int, float)) -> (float, int):
...
@typecheck
def swap_list(x: [int, float]) -> [float, int]:
...
@typecheck
def extract(k: list_of(by_regex("^[a-z]+$")),
d: dict_of(str, int)) -> list_of(int):
...
2 comments:
Is there some way to force typechecking on all methods of a class or module?
For a class you can modify its metaclass so that each new instance automatically has all of its methods instrumented with type checking.
For a module you can obtain a reference in sys.modules, walk through its methods and wrap each of them.
But both would be a bad idea. Aside from introducing unexpected side effects it would be a major performance killer. And the benefits of having everything checked upon every call are negligible. I'd say type checking is a great thing to add manually to only those methods that belong to some high level interface exposed to other application components.
Post a Comment