2012-12-10 2 views
1

Python 스크립트 안에 Python 코드를 작성한 후 실행/테스트하는 방법은 있습니까?코드를 생성하고 실행하는 Python 스크립트를 작성하는 방법이 있습니까?

내 기능 (예를 들어) 형태로 다음과 같은 종류의

def f(n): 
    if n<=3: return [0, 0, 6, 12][n] 
    return 2*f(n-1) - 4*f(n-2) - 5*f(n-3) + 15*f(n-4) 

있다하지만 테스트 동적으로 기능의 이러한 종류의 (또는 그 문제에 대한 임의의 함수)를 만들 수있을하려는 자신의 실행 중에 (이 함수를 스크립트에 복사/붙여 넣기 한 다음 수동으로 테스트하는 것과는 대조적으로) 출력합니다.

확실한가요? 필요하다면 자세한 내용을 문의하십시오. 나는 이미 eval과 exec를 살펴 봤지만 1 + 2와 같은 기본적인 구문만으로는 함수를 정의 할 수 없다.

+2

달성하고자하는 것은 _metaprogramming입니다. _ –

+0

언제이 기능을 만들 수 있습니까? 런타임 중에 "사용자 입력"에서? 또는 동적으로 당신이 시작될 때 많은 함수들을로드 할 플러그인 모듈을 제공합니까? – jdi

+0

당신은 더 구체적이어야합니다. 이러한 함수를 어떻게 작성하고 있습니까? 로컬로 정의 된 함수 (또는 람다) 나 다른 함수를 구동하는 데이터가 아닌 프로그램 텍스트 형식이어야합니까? 즉석에서 텍스트를 평가할 필요가 있다면 직접 작성해야 할 방법이 있습니다 (직접 컴파일 된 바이트 코드로 함수를 만드는 방법조차 있습니다 ...). 가능하면 그렇게하지 마십시오. 대개 잘못된 답입니다. 파이썬. – abarnert

답변

4

이런 종류의 작업을 수행하는 데는 여러 가지 방법이 있습니다.

"언어를 벗어나서"설명 할 수없는 경우 블렌더의 대답처럼 로컬 함수를 정의하고 반환 할 수 있습니다.

def make_func(a, b): 
    def f(n): 
     return n**a + b 
    return f 

때때로, 당신은 더 나은 수행 및 데이터로 기능을 나타낼 수 : 이것은 당신이 (블렌더의 예를 빌리는) 새로운 함수를 정의 할 필요가 있다고 생각하면 당신이 원하는 것을 보통이다. 예를 들어, 임의의 다항식 함수를 어떻게 생성합니까? 글쎄, 당신은 필요가 없습니다; 계수 및 값의 목록을 취하여이를 평가하는 다항식 함수를 가질 수 있습니다. 그럼 당신이해야 할 일은 계수 목록을 만드는 것뿐입니다.

사실, 여기가 당신이 원하는 것 같아요. 당신이 말하는대로 :

2 * f (n-1) - 4 * f (n-2) - 5 * f (n-3) + 15 * f * (n-4) (n-1) + f (n-2) + f (n-2) + f (n-3) + f 5 * f (n-5) 내가 필요로하는 것에 따라.

확실히 계수의리스트로 표현 될 수있다 :

def make_recursive_func(coefficients, baseval): 
    def f(n): 
     if n < len(coefficients): return baseval[n] 
     return sum(coefficient * f(n-i-1) for i, coefficient in enumerate(coefficients)) 
    return f 

그러나 당신이 이제까지 반환 된 기능을 할거야 모든 통화 인 경우, 하나의 eval_recursive_func(coefficients, baseval)를 작성하는 아마 간단 즉시 그것을 잊어 버려라.

가끔씩은 아니지만 절대로 실제로 코드를 실행해야합니다. Himanshu가 말하듯이 evalexec과 친구들이이를 수행하는 방법입니다. 예를 들면 : 당신은 그냥 할 것입니다 정확히 것처럼

newcode = ''' 
def f(n): 
    if n<=3: return [0, 0, 6, 12][n] 
    return 2*f(n-1) - 4*f(n-2) - 5*f(n-3) + 15*f(n-4) 
''' 
exec(newcode) 

이제 f 기능은 정의 된이 :

def f(n): 
    if n<=3: return [0, 0, 6, 12][n] 
    return 2*f(n-1) - 4*f(n-2) - 5*f(n-3) + 15*f(n-4) 

이 Py2보다 Py3에서 조금 다른, 그리고에 따라 차이가 있습니다 어떤 컨텍스트를 실행할지, 아니면 실행이나 평가, 컴파일 또는 가져 오기와 같은 대우 등을 원하는지 등이 있습니다. 그러나 이것이 기본 개념입니다.

두 번째 대신 첫 번째 글자를 쓰고 싶은 이유를 생각할 수 없다면이 필요가 없습니다.

그리고 올바른 문자열을 생성하는 방법을 알아낼 수 없다면이 작업을해서는 안됩니다.

Ignacio Vazquez-Abrams가 지적했듯이 이러한 기능을 사용자 입력으로 구축 할 수 있다면 대개 반복적으로 컴파일하고 AST를 따라 가면서 안전하다는 것을 확인해야합니다.

마지막으로 훨씬 더 적은 수의 다른 함수 객체 (또는 손으로 제작 한 바이트 코드)에서 바로 새 함수 객체를 만들 때 new 모듈 (및/또는 inspect)을 사용해야합니다. 그러나 당신이 그것을하는 방법을 알 필요가 있다면, 당신은 아마 이미 방법을 알고 있습니다.

+0

와우,이 작품! 이런 달콤한 엄마, 이것은 완벽하게 작동했습니다. 그것은 똑같은 간격/형식/등이 필요합니까? 이 기능을 즉시 작성하는 경우, \ ​​t을 탭에, \ r \ n을 개행에 사용해야합니까? – KaliMa

+0

글쎄, 정말 파이썬 코드로 탭을 가져서는 안된다. 그리고 당신은'\ r \ n'보다는'\ n'을 가져야합니다. 그러나 무엇을 사용하든 문자열은 스크립트에 넣거나 해석기에 입력하는 것과 똑같은 것이어야합니다. 물론'' ''문자열 대신에'\ t'와'\ n' 이스케이프를 사용할 수 있습니다. 한편, 나는 이것이 실제로하고 싶은 것이 아니라고 생각합니다 ... 특히 모듈 컴파일에 대해 배우고 싶지 않다면 ...하지만 제가 틀렸다면 어떻게할까요? 해. – abarnert

+0

"make_recursive_func"접근법이 아마도 우수하다고 생각합니다. 어떻게 실제로 f (n)을 테스트합니까? 예를 들어 – KaliMa

3

함수가 비슷하다면 다른 함수를 사용하여 만들 수있다.

g = make_func(2, 1) 
: 그냥 속으로

def g(n): 
    return n**2 + 1 

: make_func를 사용

def make_func(a, b): 
    def f(n): 
     return n**a + b 

    return f 

이 함수 정의 변환 귀하의 경우에는


,이 같은 작업을해야합니다 :

def create_f(start_condition, vars, coeff_pairs): 
    def x(n): 
     if n <= start_condition: 
      return vars[n] 

     result = 0.0 

     for coeff, shift in coeff_pairs: 
      result += coeff * x(n + shift) 

     return result 

    return x 

그리고 당신은 그것을 호출 할 수 있습니다

f = create_f(3, [0, 0, 6, 12], [(2, -1), (-4, -2), (-5, -3), (15, -4)]) 

출력은 당신의 하드 기능의 출력과 일치합니다.

+0

맞지만 때때로 다른 시작 조건, 조건의 수, 반복적 인 하위 구성 요소의 수 등이있을 수 있습니다. – KaliMa

+0

@KaliMa : 예? – Blender

+0

1 분에 2 * f (n-1) - 4 * f (n-2) - 5 * f (n-3) + 15 * f (n-4) (n-1) + f (n-3) + f (n-4) + 5 * f (n-5) + 3 * 내가 필요로하는 것에. 같은 조건이 초기 조건에 해당됩니다. n <= 5 일 수 있습니다 : [1,2,3,4,5,6] [n] 등을 반환하십시오. – KaliMa

2

완벽합니다. 파이썬은 심지어 이런 목적으로 명시 적으로 set of modules을 가지고 있습니다. 함수를 실행하기 전에 AST를 통과하고 노드를 확인하여 누군가가 os.system('rm -rf /')에 snuck하지 않았는지 확인하십시오.

+0

실제로 Google을 통해이 페이지를 보았지만 3 + 4 등의 표현식을 합성 할 수있는 항목을 찾을 수 없었습니다. – KaliMa

+0

@KaliMa : Python 2에서 'eval'함수라고 가정하면 (또는 스위트)가 아닌 표현식 만 평가할 수 있으며 표현식에서 함수를 정의 할 수 없습니다 (람다를 제외하고 - 여기서는 작동하지 않습니다. 다른 것들 중에서 재귀 적이 필요하기 때문에). – abarnert

관련 문제