На Python 3.3 вы можете использовать аннотации функций и проверить:
import inspect
def validate(f):
def wrapper(*args):
fname = f.__name__
fsig = inspect.signature(f)
vars = ', '.join('{}={}'.format(*pair) for pair in zip(fsig.parameters, args))
params={k:v for k,v in zip(fsig.parameters, args)}
print('wrapped call to {}({})'.format(fname, params))
for k, v in fsig.parameters.items():
p=params[k]
msg='call to {}({}): {} failed {})'.format(fname, vars, k, v.annotation.__name__)
assert v.annotation(params[k]), msg
ret = f(*args)
print(' returning {} with annotation: "{}"'.format(ret, fsig.return_annotation))
return ret
return wrapper
@validate
def xXy(x: lambda _x: 10<_x<100, y: lambda _y: isinstance(_y,float)) -> ('x times y','in X and Y units'):
return x*y
xy = xXy(10,3)
print(xy)
Если есть ошибка проверки, печатает:
AssertionError: call to xXy(x=12, y=3): y failed <lambda>)
Если не ошибка проверки, печатает:
wrapped call to xXy({'y': 3.0, 'x': 12})
returning 36.0 with annotation: "('x times y', 'in X and Y units')"
Вы можете использовать функцию, а не лямбда к получить имя в ошибке утверждения.
Как примечание, это, как правило, очень плохая идея - это идет вразрез с Python. Проверка типов - это плохо во всех случаях. Также стоит отметить, что для использования аргументов с аргументами может возникнуть больше смысла, если вы находитесь в 3.x. –
@Lattyware: Принудительные аргументы функции и типы возвращаемых данных являются одним из примеров в [оригинальной версии pep для декораторов] (http://www.python.org/dev/peps/pep-0318/) – jfs
В чем вопрос? –