2014-10-11 4 views
4

: 또한 함수에 인수로 호출 할 수 있습니다함수가 다른 함수의 본문에서 호출되는지 또는 함수의 인수로 호출되는지를 결정할 수 있습니까? 우리는 파이썬 함수가 있다고 가정

def funcA(): 
    func() 

FUNC() :

def func(): 
    # if called in the body of another function, do something 
    # if called as argument to a function, do something different 
    pass 

FUNC()는 다른 함수의 본문에 호출 할 수 있습니다 :

def funcB(arg1): 
    pass 

def funcC(**kwargs): 
    pass 

funcB(func()) 
funcC(kwarg1=func()) 

func() 본문에서 두 경우를 구별 할 수있는 방법이 있습니까?

EDIT. 여기에 나의 유스 케이스가있다. 규칙 기반 3D 모델 생성을위한 언어로 Python을 사용하고 싶습니다. 각 규칙은 작은 파이썬 함수입니다. 각 후속 규칙은 모델을 구체화하고 추가 세부 사항을 추가합니다. Here은 예제 규칙 집합입니다. Here은 규칙 집합이 어떻게 작동하는지 설명하는 자습서입니다. 내 규칙 언어는 CGA 모양 문법이라고하는 규칙 언어를 모방합니다. 이 StackExchange 질문을 해결할 수 있다면 제 규칙 언어가 크게 단순화 될 수 있습니다.

EDIT2. 코드 패치도 나에게 충분할 것입니다. 예를 들어 func가 다른 함수의 본문에서 호출 된 모든 경우는 다음과 같이 대체됩니다.

call_function_on_the_right()>>func() 
+0

왜이 사실을 알아야할까요? 당신의 유스 케이스는 무엇입니까? –

+2

당신처럼 실제로 두 개의 서로 다른 기능을 가지고 있습니다. –

+4

그리고 두 번째 형식은 표현식이며, 출력 *은'funcB()'의 인수로 사용됩니다. 당신은 또한'foo = func()'그리고'funcB (foo)'를 가질 수 있고 아무런 차이가 없을 것입니다. 또는'foo = func' (참고로, * call *은 같은 함수에 대한 참조), 그리고 나서'funcB (foo())'는 같은 함수 객체를 호출합니다. –

답변

1

다른 사람들은 이미 이것이 좋지 않을 수 있다고 지적했습니다. 당신은 예를 들어 사용을 요구함으로써 동일하게 성취 할 수 있습니다. toplevel에 funct()을, 인수로 funca()을 사용할 수 있으며, 모두 사용자가 최상위 또는 인수에 있는지 여부를 지정하는 키워드 인수와 함께 func()을 호출 할 수 있습니다. 그러나 나는 이것이 좋은 생각인지 아닌지에 대해 논쟁하기 위해 여기에 온 것이 아닙니다. 나는 그 질문에 대답하기 위해 왔습니다.

가능합니까? 그것은 수 있습니다.

어떻게하면 되겠습니까? 음, 가장 먼저 알아야 할 것은 inspect.stack()을 사용하여 호출 된 컨텍스트에 대한 정보를 얻을 수 있다는 것입니다.

호출 한 행을 알아 내서 소스 파일을 읽으면 해당 행에서 함수가 호출되는 방식을 확인할 수 있습니다. 그러나 두 가지 문제가 있습니다.

  1. 소스 파일이 수정되어 잘못된 정보를 제공했을 수 있습니다.
  2. func(func())을 수행하면 어떻게됩니까? 같은 라인에서 두 가지 방법으로 호출됩니다!

정확한 정보를 얻으려면 스택의 프레임 개체를 확인해야합니다. 그들은 바이트 코드를 포함하는 f_code 멤버와 마지막 명령어의 위치를 ​​포함하는 f_lasti 멤버를 가지고 있습니다. 이들을 사용하면 현재 호출중인 함수와 반환 값의 위치를 ​​파악할 수 있어야합니다. 프레임에 대해 전체 바이트 코드 (dis 모듈을 살펴보십시오)를 구문 분석해야하며, 인터프리터가 리턴 값의 위치를 ​​확인하는 데 사용하는 내부 스택을 추적해야합니다.

이제는 제대로 작동 할 것이라고 확신하지는 않지만 왜 작동하지 않을지는 알 수 없습니다. 내가 "잘못 될 수있다"는 것을 알 수있는 유일한 이유는 반환 값을 추적하는 것이 너무 어려워진다는 것입니다.그러나 한 줄의 코드 기간 동안 만 추적 할 수 있기 때문에 실제로 볼 수있는 한 "처리 불가능한"구조가 있으면 안됩니다.

나는 그것이 쉽다는 말은하지 않았지만, 가능할 수도 있습니다. :)

+0

"소스 파일은 수정되어 잘못된 정보를 제공합니다. " 사례에 대해 설명하거나 사례를 제공해주십시오. – vvoovv

+0

귀하의 메시지 덕분에, 나는 아이디어를 얻었습니다. 나는 func() 전에 여러개의 둥근 괄호를 셉니다. 숫자가 짝수이면 func()가 함수 본문에서 호출됩니다. 숫자가 이상한 경우. func()는 함수의 인수로 호출됩니다. 그게 효과가 있다고 생각하니? – vvoovv

+0

@vvoovv 예를 들어 누군가가 "라이브러리"를 사용하고 그 라이브러리를 사용하는 자체 "파트 라이브러리"와이를 사용하는 두 개의 개별 프로그램이있는 경우 첫 번째 프로그램을 시작한 다음 두 번째 프로그램 프로그램 요구. 이제 첫 번째 실행 프로그램이 잘못된 소스 코드를보고 있습니다. 예. 소스 코드를 사용하는 프로그램이 실행되는 동안 소스 코드를 수정할 때마다 언제든지 완전히 손상됩니다. (예를 들어, 누군가가 .pyc 파일 만 배포하는 경우) 또한, 괄호 계산 솔루션을 깨뜨릴 수있는 많은 물리적 라인에서 논리적 라인을 끊을 수 있습니다. (그리고 심지어 당신의 예제 파일은 그렇게한다) –