58 lines
1.5 KiB
Python
58 lines
1.5 KiB
Python
# -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
|
|
|
"""Des fonctions pour travailler avec les fonctions.
|
|
"""
|
|
|
|
__all__ = ('apply_args', 'unpack_results')
|
|
|
|
from types import MethodType, FunctionType
|
|
|
|
from .uio import _s
|
|
from .base import isseq
|
|
|
|
def apply_args(func, *args, **kw):
|
|
u"""Appliquer à la fonction func les arguments args, en tenant compte du
|
|
nombre de ses arguments et en ignorant les arguments "en trop".
|
|
|
|
Par exemple, si f est défini ainsi:
|
|
|
|
def f(a, b):
|
|
pass
|
|
|
|
Alors:
|
|
|
|
apply_args(f, 1, 2, 3)
|
|
|
|
Est équivalent à:
|
|
|
|
apply(f, (1, 2))
|
|
"""
|
|
f = func
|
|
ac_offset = 0
|
|
if type(f) is MethodType:
|
|
f = f.im_func
|
|
ac_offset = 1
|
|
if type(f) is not FunctionType:
|
|
raise ValueError("func must be a function")
|
|
argcount = f.func_code.co_argcount - ac_offset
|
|
args = args[:argcount]
|
|
return func(*args, **kw)
|
|
|
|
def unpack_results(results, *defaults):
|
|
u"""results étant une valeur scalaire ou une séquence, retourner une
|
|
séquence ayant le même nombre de valeurs de defaults, et en fournissant
|
|
les valeurs de defaults si elles ne sont pas présentes dans results.
|
|
|
|
>>> unpack_results((1,2), "a", "b", "c")
|
|
(1, 2, 'c')
|
|
>>> unpack_results("x", "a", "b", "c")
|
|
('x', 'b', 'c')
|
|
"""
|
|
if not isseq(results): results = (results,)
|
|
expected = len(defaults)
|
|
got = len(results)
|
|
head = tuple(results[:expected])
|
|
if got < expected: tail = tuple(defaults[-(expected - got):])
|
|
else: tail = ()
|
|
return head + tail
|