python - A decorator which converts string to number -
this question has answer here:
i use decorators convert numbers in string format int/float value, here how trying it
def str_to_int(func): """ wrapper converts string value integer """ def wrapper(*args, **kwargs): arg in args: arg = int(arg) return func(*args, **kwargs) return wrapper @str_to_int def number_as_string(a, b, c): return a,b,c print (number_as_string('1', '2', '3'))
output
('1', '2', '3')
however, wanted below
(1, 2, 3)
the above output generate below code
def str_to_int(func): """ wrapper converts string value integer """ def wrapper(x, y, z): return int(x), int(y), int(z) return wrapper @str_to_int def number_as_string(a, b, c): return a,b,c print (number_as_string('1', '2', '3'))
but above code defeats purpose of using decorator @ first place, since convert string values irrespective of arguments original function has.
could 1 suggest wrong first program , how resolve it.
the reason not working expected because never update incoming args
, keep overwriting value in loop.
consider revised version:
>>> def str_to_int(f): ... def wrapper(*args, **kwargs): ... args = map(int, args) ... return f(*args, **kwargs) ... return wrapper ... >>> @str_to_int ... def foo(a,b,c): ... return a,b,c ... >>> foo('1','2','3') (1, 2, 3)
the key list line:
args = map(int, args)
it makes sure original args tuple replaced completely, in loop silently discarding value.
for python3, should use:
args = tuple(map(int, args))
as map return map object.
of course hope realize decorator works if pass things can converted numbers, if pass in string raise valueerror
:
>>> foo('hello') traceback (most recent call last): file "<stdin>", line 1, in <module> file "<stdin>", line 3, in wrapper valueerror: invalid literal int() base 10: 'hello'
if want prevent that, have ignore values cannot converted integer:
def wrapper(*args, **kwargs): _temp = [] in args: try: _temp.append(int(i)) except valueerror: _temp.append(i) args = tuple(_temp) return f(*args, **kwargs)
now ignore things cannot convert:
>>> foo('hello', '1', '2') ('hello', 1, 2)
you can shorten code bit, *
automatically expand arguments, can use advantage:
# args = tuple(_temp) return f(*_temp, **kwargs)
Comments
Post a Comment