2017-02-12 5 views
1

+, -과 같은 기본 연산을 원하는 클래스를 정의하고 sin과 같은 고급 연산을 지원하도록 정의했습니다. 즉,이 기본 연산자와 수학 함수에 대한 몇 가지 새로운 규칙을 정의해야합니다.수학 및 numpy 모듈에서 기존 함수를 사용자 정의 객체를 지원하려면 어떻게합니까?

나는 다음과 같이 파이썬의 마술 방법을 사용하여 기본 운영 다룰 수

,

class NewObj(): 

    def __init__(self, *args): 
     pass 

    def __add__(self, other): 
     pass 

    def __mul__(self, other): 
     pass 

    # Use magic methods to define other basic operators below... 

그리고 나는 또한 클래스 NewObj가 정의 같은 평 파일에 기본 기능을 재정의 할 수있는, 그런

def sin(x): 
    pass 

그리고이 파일의 이름을 myoperator.py로 지정하십시오. 그런 다음이 모듈을 가져 와서 NewObj 개체에 새로운 작업을 적용 할 수있었습니다.


은 그러나 나는 또한 math.sin()numpy.sin()도 내 새롭게 정의 NewObj 객체를 지원하도록 내 NewObj 객체를 지원하기 위해 numpymath의 기존 기능을합니다. 이것을 어떻게 할 수 있습니까?

또 다른 질문은 : 마법의 메서드처럼 내 NewObj 클래스 안에 함수를 캡슐화하여 모든 데이터가 클래스 데이터 구조 내에 작성되도록 할 수 있습니까?

답변

3

math.sin 같은 함수는 항상 수레를 돌려 명시 적으로 math 모듈 문서. math.sin(your_object)float 대신 NewObj 인스턴스를 반환하도록하려면을 입력하십시오. 이 아닙니다. 심지어 작동하게 만들면 모든 사람을 혼란스럽게 할 것이며, 초기화 명령 버그 및 기타 두통을 유발할 것입니다. NumPy 배열을 지원하기 위해 math.sin을 만드는 대신 NumPy에 자체 numpy.sin이있는 이유가 있습니다.,

class NewObj(object): 
    ... 
    def __float__(self): 
     return whatever 

math.sin은 float로 개체를 변환합니다 플로트의 사인을 계산 :)

당신이 float를 반환 math.sin(your_object)로 괜찮 경우

, 다음 수레에 객체를 변환하는 __float__ 메소드를 구현 , 사인을 실수로 반환합니다.

class NewObj(object): 
    ... 
    def sin(self): 
     return whatever 

numpy.sin

sin 방법에 위임됩니다


NumPy와를 들어, 단지 sin 방법을 구현한다. 당신은 NewObj을 반환 할 수 있습니다; 부유물 등으로 캐스팅 할 필요가 없습니다. 가장 유사한 NumPy 함수는 비슷한 방식으로 위임합니다. NumPy 배열 내에서 사용자 지정 개체를 사용하려고하면 NumPy의 효율성 이점 대부분이 무너 지므로 원하는 경우 디자인을 다시 생각해 볼 수 있습니다.

+0

대답의 'numpy'비트를 다시 입력하십시오. 이것은 매우 유용하게 보입니다. 현재 '__array_priority__'및 친구들과 어떻게 관련이 있습니까? 그리고 그 미래에 대한'__numpy_ufunc__'는 무엇입니까? 포인터를 제공 할 수 있습니까? 감사! –

+0

@PaulPanzer : 나는이 상황에서'__array_priority__'가 나오지 않을 것이라고 생각합니다. '__numpy_ufunc__'에 대해서는'__numpy_ufunc__'가 어떻게 상호 작용하는지 모르겠습니다. – user2357112

2

math 모듈의 sin을 재정의 할 수 있습니다.

import math 

class NewObj: 
    pass 

old_sin = math.sin 

def new_sin(number): 
    return 42.0 if isinstance(number, NewObj) else old_sin(number) 

math.sin = new_sin 

아마 42.0을 더 유용한 정의로 바꿀 것입니다.

+0

나를 위해 일합니다. 내가'수입 수학을 쓰면; myoperator를 mo로 가져옵니다. print (math.sin (mo.NewObj()))'를 실행하여'42.0'을 출력합니다. CPython 3.6.0을 사용하고 있습니다. –

+0

'math.sin'을 호출 할 수 있으려면 스크립트에서'import math'를 명시 적으로 가져야합니다. 그렇지만'import myoperator'는'math.sin'의 동작을 재정의합니다. 이 나쁜 점을 고려하지 않은 이유는'math.sin'의 재정의가 이미 정의 된 데이터 유형에 대한 작동 방식을 변경하지 않기 때문입니다. 적용 할 수있는 새로운 유형 만 추가하므로 변경으로 인해 다른 코드가 손상되지 않아야합니다. –

+0

나는 지금 (나를 위해 일한다), 고마워한다! – Nicholas

1

미래에는 아마도 __numpy_ufunc__ 특수 속성 (이름은 change)이 될 것입니다. 여기에 관련 비트 버전 1.11에서 NumPy와 문서 'dev version

class.__numpy_ufunc__(ufunc, method, i, inputs, **kwargs)

에서 New입니다.

모든 클래스 (ndarray 하위 클래스 또는)는이 메서드를 정의하여 NumPy의 ufuncs 동작을 재정의 할 수 있습니다.

[강조 광산]

+2

@MadPhysicist는 "전혀 대답하지 않습니다"? Q를 읽으면 OP가 '수학'과 'numpy'기능을 아주 구체적으로 요구하고 있음을 알게 될 것입니다. 그래서 이것은 50 %를 커버합니다. 그리고 마법 방법 태그가 있습니다. ufuncs가 아닌 Numpy 함수는 여기서는 거의 관련이 없습니다. 게다가, 왜이 부정적인 태도? –

+0

꽤 형식화가 잘되어 있다면, 나는 '대답'에있는 정보를 주석보다 더 선호한다. 하지만 이것이 OP 케이스에서 도움이되는지 확신 할 수 없습니다. ndarray 서브 클래스가'ufunc'에 특별한 동작을 필요로 할 때 더 유용 할 것 같습니다. 'ufunc'를 정의하는 것은 아마도 OP의 필요를 초월 할 것입니다. – hpaulj

+0

@hpaulj 글쎄, 그것은 "모든 클래스 (ndarray 하위 클래스 또는 아닙니다)"라고 말합니다. 그러나 나는 그것이 모두 어떻게 맞는지 이해하지 못합니다. –