4

클래스가 Function이고, 인스턴스가 하나의 인수를 사용하는 호출 가능 객체라고 가정합니다. 나는이 클래스들에 대해 pointwise 산술을 직접적으로 정의했다. 여기에 내 코드의 단순화 된 버전이다 (실제로 __init____call__에서 더 복잡한 동작을하지만,이 질문에 대한 무관의) :암시 적 유형 변환을 통한 점진적 산술 구현

class Function: 
    ''' 
    >>> f = Function(lambda x : x**2) 
    >>> g = Function(lambda x : x + 4) 
    >>> h = f/g 
    >>> h(6) 
    3.6 
    ''' 
    def __init__(self, func): 
    self.func = func 
    def __call__(self, value): 
    return self.func(value) 
    def __truediv__(self, other): 
    if isinstance(other, Function): 
     return Function(lambda x:self(x)/other(x)) 
    else: 
     return NotImplemented 
    # ... 

내가 암시 적 형식 변환을 허용하려고 할 때이 붙어있어. 예를 들어, 내가 쓸 수 있어야합니다 : 즉

>>> f = Function(lambda x : x ** 2) 
>>> g = f+1 
>>> g(5) 
26 

을하는 Function 인스턴스에, 내가 Function(lambda x : v)v을 변환 할 옆에 내가 산술 식에 숫자 객체 v을 볼 때마다.

또한 사용자 정의 유형 중 일부에 대해 비슷한 동작을 수행하고자합니다. 다시 한 번 Function 객체가있는 동일한 이진 산술 표현식에서 볼 수 있습니다.

이 논리를 정규 및 반영된 이진 산술 연산자 (각각 isinstance(v, numbers.Number)isinstance(v, MyUserDefinedType)을 확인하는 것)로 확실하게 코딩 할 수 있지만 좀 더 우아한 방법이있을 것이라고 생각합니다.

내 디자인에서 가능한 다른 개선 사항이있는 경우 알려 주시기 바랍니다. (Function 개체는 거의 생성되지 만, 매우 자주라는, 그래서 성능은 약간의 관심입니다 수 있습니다.)

편집 :

에릭의 코멘트 @ 해결하기 위해, 나는 다른 사용자 정의 클래스 Functional을 명확히해야합니다

class Functional: 
    ''' 
    >>> c = [1, 2, 3] 
    >>> f = Functional(lambda x : x + 1) 
    >>> f(c) 
    [2, 3, 4] 
    >>> g = Functional(lambda x : x ** 2) 
    >>> h = f + g 
    >>> h(c) 
    [3, 7, 13] 
    ''' 
    def __init__(self, func): 
    self.func = func 
    @staticmethod 
    def from_function(self, function): 
    return Functional(function.func) 
    def __call__(self, container): 
    return type(container)(self.func(c) for c in container) 
    def __add__(self, other): 
    if isinstance(other, Functional): 
     return Functional(lambda x : self.func(x) + other.func(x)) 
    else: 
     return NotImplemented 

I 볼 때 Function 모두가 동일한 연산 식에 Functional 인스턴스가 I가 Function 암시 Functional.from_function 방법을 사용 Functional로 변환하려는.

그래서, 암시 적 형식 변환 계층은 다음과 같이 진행됩니다

  • 기능
  • 기능
  • 무엇

그리고 암시 적으로이에서 가장 높은 유형으로 변환하고 싶습니다 주어진 산술 표현식에서 보이는 계층 구조. 모든 사업자에 대해이 같은

+0

, 당신은 모든 비'Function'를 변환하고 싶지 않은 : 나는 단번에 모두 FunctionFunctional을 처리 할 수 ​​좋아하지만, 나는 성능면에서 매우 비싼 수 있습니다 무서워 그들의 람다에 상응 하는가? – Eric

+0

@Eric 거의 .. 사실상 상위 수준의 클래스 인 'Functional'이 있습니다.이 클래스는 값의 컨테이너에서 작동합니다 (특정 함수에 의해 처리되는 각 값이있는 새 컨테이너를 만듭니다). 'Function'과'Functional'이 같은 표현식에있을 때, 둘 다'Functional'으로 변환되기를 원합니다. 그 외에는 네 말이 맞아. 내 질문을 업데이트 할게. – max

+0

"무력"이 무슨 뜻인지 확실하지 않습니다. 인수가 함수 또는 클래스의 인스턴스 인 경우'obj'를 반환하는 유틸리티 함수'funcOrLambda (obj)'를 쓸 수 없습니까? 그렇지 않으면'lambda x : obj' (또는 필요한 모든 논리)를 반환합니다. ? 그렇다면 모든 마법 방법에서 논리를 반복 할 필요가 없습니다. – BrenBarn

답변

2

뭔가 잘 작동 :

def __truediv__(self, other): 
    if callable(other): 
     return Function(lambda x:self(x)/other(x)) 
    else: 
     return Function(lambda x:self(x)/other) 
+0

고마워, 그게 효과가있는 것 같아서, 내가 현재 시도하고있는 솔루션보다 훨씬 빠를 것이다. (나는 초에 게시 할 것이다). 하지만 필자는'Functional'을 별도로 다뤄야 할 것입니다. – max

1

하나의 옵션이 Function 클래스의 모든 사업자들이 경우 기본 함수의 결과에 적용되는 임의의 값을 받아 들일 수 있도록하는 것입니다 자신이 기능하지 않습니다.예를 들어, f가 함수 인 경우, 단순히 당신이 가지고있는 __truediv__ 구현 수정 f/5을 허용 연장 : 당신은 선택적으로 확인하십시오 제정신이야하게 확인 몇 가지 유형을 할 수

def __truediv__(self, other): 
    if isinstance(other, Function): 
     return Function(lambda x:self(x)/other(x)) 
    else: 
     return Function(lambda x:self(x)/other) 

를 (그리고 오류를 발생 초기보다는 나중에 on),하지만 그것 없이는 작동합니다.

+0

Thx ..'if isinstance (other, Function)'보다는 오히려'callable '을 체크하는 좀 더 일반적인 접근법으로 갈 것입니다. 왜냐하면'Function'이 내장 함수의 인스턴스가 아니기 때문입니다 '나는'function'을 서브 클래스화할 수 없다는 것입니다 ... 그래서 모든 호출 가능 객체는'Function' 인스턴스와 같습니다. – max

0

의견 및 기타 답변을 읽은 후이 방법을 시도했습니다. 의견을 요청하기 위해 게시하고 있습니다. 일반적으로

class Function: 
    ''' 
    >>> f = Function(lambda x : x**2) 
    >>> g = Function(lambda x : x + 4) 
    >>> h = f/g 
    >>> h(6) 
    3.6 
    >>> k = f + 1 
    >>> k(5) 
    26 
    >>> m = f + (lambda x : x + 1) 
    >>> m(5) 
    31 
    ''' 
    def __init__(self, arg): 
     if isinstance(arg, Function): 
      self.func = arg.func 
     elif callable(arg): 
      self.func = arg 
     else: 
      self.func = lambda x : arg 
    def __call__(self, value): 
     return self.func(value) 
    def __truediv__(self, other): 
     return self.__class__(lambda x:Function(self)(x)/Function(other)(x)) 
    def __rtruediv__(self, other): 
     return self.__class__(lambda x:Function(other)(x)/Function(self)(x)) 
    def __add__(self, other): 
     return self.__class__(lambda x:Function(self)(x)+Function(other)(x)) 
    def __radd__(self, other): 
     return self.__class__(lambda x:Function(other)(x)+Function(self)(x)) 
    # ... 


class Functional(Function): 
    ''' 
    >>> c = [1, 2, 3] 
    >>> f = Functional(lambda x : x + 1) 
    >>> f(c) 
    [2, 3, 4] 
    >>> g = Functional(lambda x : x ** 2) 
    >>> h = f + g 
    >>> h(c) 
    [3, 7, 13] 
    ''' 
    def __call__(self, container): 
     return type(container)(self.func(c) for c in container) 
관련 문제