2011-10-18 3 views
25

기본적으로, 내가 뭘하려는 있습니다 :특정 위치 인수를 파이썬에서 partial로 채우는 방법?

>>> 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으로 특정 위치 인수를 채우는 방법.

P. 대신 lambda을 사용할 수 있다는 것을 알고 있습니다.

+1

앞서 가서'lambda'를 사용합니다. 'partial'이 C에서 구현되기 때문에 약간 느려질 것입니다. 성능이 프리미엄 인 경우 C에서 변형을 구현할 수도 있습니다. – wberry

답변

32

할 수 없습니다. 래퍼 함수를 ​​만들어야합니다.

표면 상으로는 키워드 매개 변수를 사용해 보았습니다. 그게 바로 그 때문입니다. 불행히도, 파이썬의 표준 라이브러리 함수 인 do not take named parameters을 발견했습니다. 따라서 간섭을 실행하는 다른 기능을 만들지 않고 현재 구현 된 partial을 부여 할 수는 없습니다.

가 포함되도록 허용 무슨 PEP 309의 승인에 따라, "생성자 좌단 인수 위치와 키워드를 입력 결합() 부분"이었다. 또한,이 상태 :이 함수 것처럼 객체 호출 할 때

하는 것으로, 위치 인수 생성자에 제공된 것과를 첨부 이 있으며, 키워드 인자는 무시하고 생성자에 제공된 보강.

개체를 만들 때 및 호출 할 때 위치 인수, 키워드 인수 또는 둘 모두를 제공 할 수 있습니다. 추가 위치 인수가 을 추가되기 때문에

는 (이 구현에 의해) 일부 이전 위치 인수를 제공 할 방법이 없습니다.

그러나 간다 : 자체 문제를 야기 임의의 위치에서 오른쪽 또는 삽입 인수 에서

부분적인가 인자이지만 양호한 구현 비 혼동 의미론 보류 발견 나는 그것이 배제되어야한다고 생각하지 않는다.

그래서 분명히 테이블 위에있을 수는 있지만 그대로서는 것은 아닙니다.

공개를 위해 위의 인용문을 강조한 내용은 저만의 것이 었습니다.

0

사용이 코드 :

# 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) 
3

당신은 정말 당신이 funcy 타사 라이브러리에서 rpartial를 사용이 필요합니다.

그 코드는 여기에 있습니다 :

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

이 그래서, 당신의 경우는 다음과 같이 처리 할 수 ​​있습니다 :

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