Как заполнить определенные позиционные аргументы частичным в python?

В основном, я бы хотел сделать следующее:

>>> from functools import partial >>> partial(str.startswith, prefix='a')('a') Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: startswith() takes no keyword arguments 

Но в более общем плане вопрос заключается в том , как заполнить конкретные позиционные аргументы partial .

PS Я понимаю, что вместо этого я могу использовать lambda .

3 Solutions collect form web for “Как заполнить определенные позиционные аргументы частичным в python?”

Это невозможно. Вы должны сделать функцию обертки.

Якобы, вы бы использовали аргументы ключевых слов, как вы пытались сделать – для чего они нужны, не так ли? К сожалению, как вы обнаружили, стандартные функции библиотеки python не принимают именованные параметры . Таким образом, это невозможно, учитывая текущую реализацию partial не создавая другой функции для запуска помех.

Согласно принятию PEP 309 , то, что было принято для включения, было «конструктор типа partial (), связывающий левые позиционные аргументы и любые ключевые слова». Кроме того, в нем говорится:

Обратите внимание, что когда объект вызывается, как если бы это была функция, позиционные аргументы добавляются к тем, которые были предоставлены конструктору, а аргументы ключевого слова переопределяют и дополняют те, которые предоставляются конструктору.

Позиционные аргументы, аргументы ключевых слов или и то, и другое могут предоставляться при создании объекта и при его вызове.

Поскольку дополнительные позиционные аргументы добавляются , не было бы способа предоставить какой-либо предшествующий позиционный аргумент (этой реализацией).

Однако это продолжается:

Частично применяя аргументы справа или вставляя аргументы на произвольные позиции, возникают свои проблемы, но, ожидая обнаружения хорошей реализации и не путающей семантики, я не думаю, что это должно быть исключено.

Таким образом, он, по-видимому, может быть на столе, но, поскольку он стоит, он не реализован именно так.

Для раскрытия, акцент в приведенных выше цитатах был моим собственным.

Если вам это действительно нужно, вы можете использовать rpartial из funcy сторонней библиотеки.

Его код здесь:

 def rpartial(func, *args): return lambda *a: func(*(a + args)) 

Таким образом, ваш случай можно обработать следующим образом:

 >>> startswith_a = rpartial(str.startswith, 'a') >>> startswith_a('abc') True >>> startswith_a('def') False 

Используйте этот код:

 # See: functoolspartial for binding... class Function(object): def __init__(self, fn): self.fn = fn def __call__(self, *args, **kwargs): return self.fn(*args, **kwargs) def __add__(self, other): def subfn(*args, **kwargs): return self(*args, **kwargs) + other(*args, **kwargs) return subfn class arg(object): """Tagging class""" def __init__(self, index): self.index = index class bind(Function): """Reorder positional arguments. Eg: g = f('yp', _1, 17, _0, dp=23) Then g('a', 'b', another=55) --> f('yp', 'b', 17, 'a', dp=23, another=55) """ def __init__(self, fn, *pargs, **pkwargs): # Maximum index referred to by the user. # Inputs to f above this index will be passed through self.fn = fn self.pargs = pargs self.pkwargs = pkwargs self.max_gindex = max( (x.index if isinstance(x, arg) else -1 for x in pargs), default=-1) def __call__(self, *gargs, **gkwargs): fargs = \ [gargs[x.index] if isinstance(x, arg) else x for x in self.pargs] + \ list(gargs[self.max_gindex+1:]) fkwargs = dict(self.pkwargs) fkwargs.update(gkwargs) # Overwrite keys return self.fn(*fargs, *fkwargs) по # See: functoolspartial for binding... class Function(object): def __init__(self, fn): self.fn = fn def __call__(self, *args, **kwargs): return self.fn(*args, **kwargs) def __add__(self, other): def subfn(*args, **kwargs): return self(*args, **kwargs) + other(*args, **kwargs) return subfn class arg(object): """Tagging class""" def __init__(self, index): self.index = index class bind(Function): """Reorder positional arguments. Eg: g = f('yp', _1, 17, _0, dp=23) Then g('a', 'b', another=55) --> f('yp', 'b', 17, 'a', dp=23, another=55) """ def __init__(self, fn, *pargs, **pkwargs): # Maximum index referred to by the user. # Inputs to f above this index will be passed through self.fn = fn self.pargs = pargs self.pkwargs = pkwargs self.max_gindex = max( (x.index if isinstance(x, arg) else -1 for x in pargs), default=-1) def __call__(self, *gargs, **gkwargs): fargs = \ [gargs[x.index] if isinstance(x, arg) else x for x in self.pargs] + \ list(gargs[self.max_gindex+1:]) fkwargs = dict(self.pkwargs) fkwargs.update(gkwargs) # Overwrite keys return self.fn(*fargs, *fkwargs) 

Затем попробуйте:

 def myfn(a,b,c): print(a,b,c) bind(myfn, arg(1), 17, arg(0))(19,14) 
  • У Python есть неизменный список?
  • Является ли список зарезервированных слов и встроенных языков Python доступными в библиотеке?
  • Как фильтровать dict для выбора только ключей, превышающих значение?
  • Разделяйте типы расширений в Cython для статической типизации
  • ImportError: не может импортировать имя Counter
  • Почему __init__.py не вызывается?
  • Python "шоу в искателе"
  • как организовать файлы с помощью python27 app engine webapp2 framework
  • Python - лучший язык программирования в мире.