Как использовать functools.partial с os.path.join?
Есть список путей + имена файлов, все начинаются с того же root_dir
, Как использовать частичное?
попытка
from os.path import join as path_join
from functools import partial
from tempfile import gettempdir
root_dir = gettempdir()
root_join = partial(path_join, path=root_dir)
root_join('foo')
Однако это выдает ошибку:
TypeError: join () получил несколько значений для ключевого аргумента path
Очевидно, я могу написать новую функцию:
root_join = lambda root=root_dir, *a: path_join(root_dir, *a)
Однако я хотел бы решить эту проблему с помощью partial
, Любая подсказка, как?
2 ответа
Просто отбросьте аргумент ключевого слова, и он будет работать:
root_join = partial(path_join, root_dir)
Образец вывода:
>>> print root_join('foo')
/tmp/foo
Explaination
partial()
принимает обернутые функции как ключевые аргументы, так и позиционные аргументы, которые объединяются с аргументами, передаваемыми при вызове результирующей частичной функции, поэтому:
partial_func = partial(func, positional_1, positional_2, keyword_1='A', keyword_2='B')
partial_func(positional_3, keywork_2='B')
Является эквивалентом:
func(positional_1, positional_2, positional_3, keyword_1='A', keyword_2='B')
Обратите внимание, что позиционные аргументы объединяются по порядку: сначала от частичного, а затем от входящего во время вызова. Как всегда, они также предшествуют ключевым аргументам.
Это означает, что ваш код:
root_join = partial(path_join, path=root_dir)
root_join('foo')
Было эквивалентно:
path_join('foo', path=root_dir)
Здесь "foo" задается как path
аргумент os.path.join(path, *p)
позиционно, а затем есть попытка назначить path
в качестве ключевого аргумента, а также.
В соответствии с os.path.join()
определение, имя первого аргумента для os.path.join()
является path
, Так что поставка path
Параметр как аргумент именованного ключевого слова через functools.partial
генерирует попытку передачи нескольких значений по одному и тому же ключу.
поскольку functools.partial()
также поддерживает предоставление позиционного аргумента, вы можете попробовать это:
>>> import functools
>>> import os.path
>>> root_join = functools.partial(os.path.join, 'root')
>>> root_join('path/to/somewhere')
'root/path/to/somewhere'