2017-11-27 17 views
1

이것은 Sage에 관한 질문입니다. Sage는 Python 2.7을 기반으로합니다. 저는 현자 질문 here을 작성했지만 그 질문을 수정하여 수학적 문맥을 제거합니다."바꾸기"특정 함수 호출

매우 구체적인 경우에 몇 가지 느린 기능의 속도를 향상 시키려고합니다. 본질적으로, 나는 foo과 같은 foo(args)이 전통적으로 상당히 느리지 만 분석으로 인해 foo(args')bar(args')을 통해 쉽게 계산할 수 있습니다 (실제로는 확인하기 쉬운 args'의 특별한 경우) . 나는 새로운 버전을 가지고 싶습니다 foo 같은 그 : 그냥

  • bar(args)을 그렇지 않으면 호출 (Abar가에 대한 올바른 모든 입력을 포함 일부 데이터 구조 또는 args in A)

    1. 하면 args == args', foo 그냥 내 자신의 코드에 정의 된 경우, 그것은 지금 foo(args)

    호출이 (정의, 또는 잠재적으로 장식을 수정하여) 해결하기 위해 사소한 것입니다.

    내 문제는 foomodule1 (내 코드 아님)입니다. module2을 가져오고 foo도 가져오고이 변경 사항을 module2의 모든 항목에 표시하고 싶습니다. (본질적으로 나 자신도 foo이라고 부르지 않습니다. 따라서 속도 향상을 위해 특정 사례를 더 빨리 계산할 다른 기능이 필요합니다.)

    module1module2을 가져 오는 내 자신의 코드가 있습니다. 이 특별한 경우를 더 빨리 처리하기 위해 foo (내 코드에서)을 수정할 수있는 방법이 있습니까? module1module2의 기능을 호출해도 속도 향상을 얻을 수 있습니까? 이는 module1module2의 소스 코드를 수정하지 않고 가능한 경우에만 유용합니다.

    편집 아래의 대답에 비추어

    , 세이지의 PARI에 원숭이 패치 호출 할 수있는 방법이 있습니까? 원숭이 패치를 시도하는 방법은 프로파일 러에 의해 {method '_nf_rnfeq' of 'sage.libs.cypari2.gen.gen' objects}으로 설명됩니다. 이것에 비추어, 나는 다음을 시도했다. 그것은 효과가 없었다.

    import sage.libs.cypari2.gen 
    orig_nf_rnfeq = sage.libs.cypari2.gen.gen._nf_rnfeq 
    def _nf_rnfeq(*args, **kwargs): 
        print("Rnfeq works!") 
        return orig_nf_rnfeq(*args, **kwargs) 
    
    sage.libs.cypari2.gen.gen._nf_rnfeq = _nf_rnfeq 
    

    이 오류 TypeError: can't set attributes of built-in/extension type 'sage.libs.cypari2.gen.gen

  • 답변

    1
    import module1 
    origfoo = module1.foo 
    
    def myfoo(*args): 
        if args in A: 
         return bar(*args) 
        return origfoo(*args) 
    
    module1.foo = myfoo 
    

    함수의 수정 된 버전을 선택할 것이 시점 이후 module1을 가져 모든 모듈에 연결됩니다. module1이 패치를 적용하기 전에 module2을 가져 오는 경우 문제가 발생할 수 있습니다.

    +0

    이 구현하려고하면 다음 오류가 발생합니다.'TypeError : 내장/확장 유형 'sage.libs.cypari2.gen.gen'의 특성을 설정할 수 없습니다. 그것은 [여기] (https://stackoverflow.com/questions/192649/can-you-monkey-patch-methods-on-core-types-in-python)와 관련된 것으로 보이므로 그. – Mark