2013-07-10 4 views
0

주어진 n에 대해 산술 mod n을 수행 할 프로그램을 작성하려고합니다. Python (2.7이 선호 됨) 내에 동적으로 함수를 정의하여 그 동작을 호출하는 데 사용 된 이름에 따라 달라 지는지 궁금합니다. 보다 구체적으로, "* mod"라는 함수를 정의하고 싶습니다. *는 정수이고, 그 다음에 산술적 인 mod *를합니다. 아마도 더 명확하게, 2mod, 3mod, 4mod 등의 함수를 정의하는 * mod에 대한 하나의 함수 정의를 작성하고 싶습니다. 이것이 가능한가? 비슷한 질문이 이미 제기되었거나 나의 답변이 문서에서 즉시 이용 가능하면 사과드립니다. 검색을 시도했지만 찾고있는 기능을 정확하게 설명하는 방법을 알지 못해서 놓친 것 같습니다.Python에서 함수 이름으로부터 입력 받기

감사합니다.

+2

파이썬의 식별자 (함수 이름 포함)는 숫자로 시작할 수 없습니다. 숫자를 인수로 취하는 함수를 만드는 대신 왜 이것을하고 싶습니까? – BrenBarn

+1

이 특별한 경우에는 "%"연산자를 직접 사용하지 않으려 고 할 이유가 없습니다. –

답변

0

함수를 문자열로 생성 한 다음 exec 문자열을 사용하면 현재 네임 스페이스에서 함수를 가져올 수 있습니다. 이 함수 당신은 그렇게하고 싶지 않아 mod2(x)

+0

[eval is dangerous] (http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html) – TerryA

4

을 정의 할

n = 2 
s = 'def mod%i(x):' % n 
s += ' return x %% %i' % n 
exec s 

:처럼 뭔가. 다만 인수로 두 숫자를 간단한 함수를 만들어 전달합니다

def mod(x, n): 
    return x % n 

print mod(5, 2) 
# 1 
+0

손으로 편리한 기능 *을 정의 할 수 있습니다. –

1

globals를 사용하여, 람다 :

for i in range(2, 5): 
    globals()['mod{}'.format(i)] = lambda x, n=i: x % n 

assert mod2(4) == 0 
assert mod2(3) == 1 
assert mod3(2) == 2 
assert mod3(1) == 1 
assert mod4(1) == 1 
assert mod4(2) == 2 
assert mod4(3) == 3 
assert mod4(9) == 1 
3

글쎄, 당신이 정말로, 정말이이 빠른 해킹을보고합니다. 그것은 uses a wrapper class 클래스에 모듈을 포장하는, 그래서 당신은 __getattr__를 사용할 수 있습니다

import sys 
import functools 

def add(a, b): 
    return a + b 

def sub(a, b): 
    return a - b 

class Wrapper(object): 
    def __init__(self, wrapped): 
     self.wrapped = wrapped 
    def __getattr__(self, name): 
     try: 
      # quick hack. Don't try this at home :-) 
      f = ''.join(x for x in name if not x.isdigit()) 
      n = ''.join(x for x in name if x.isdigit()) 
      return functools.partial(getattr(self.wrapped, f), int(n)) 
     except: 
      return getattr(self.wrapped, name) 

sys.modules[__name__] = Wrapper(sys.modules[__name__]) 

을 이제, 예를 호출 할 때 add10(12)이 모듈에서 결과는 22입니다. 메소드 이름은 숫자로 시작하면 안되며, _add과 같은 이름을 사용하고 _55add(45)과 같은 메소드를 호출 할 수 있습니다.

그러나 나는 Haidro advice을 따를 것입니다 : 을 원하지 않습니다. 두 개의 인수로 메소드를 호출하는 것이 훨씬 간단합니다.

+0

이것은 정말로 영리합니다. 특히,'sys.modules'에서 모듈을 수정하여 활성 코드 항목이되도록하십시오! 여러분의 링크에서 언급했듯이, 이것은 마술을'import'ed시켜야하기 때문에,'sys.modules' 트릭이 그 일을 할 수 있도록 모듈로 감겨져 있어야합니다. 나는 그것을 사용하지 않지만 파이썬 파워를 실제로 보여줍니다! :-) – torek