2013-03-19 1 views
1

모듈의 각 함수에 대한 인수 유형을 확인하려고합니다 (inspect 모듈을 사용하지 않고). 내가 해낸 가장 쉬운 해결책은 각 기능을 개별적으로 검사하는 것입니다.단일 인터페이스를 사용하여 여러 함수에 대한 인수 유형 유효성 검사 (inspect 사용하지 않음)

def func1(num1, num2): # the two params must be integers 
    if isinstance(num1, int) and isinstance(num2, int): 
     # ...function code... 
     pass 
    else: 
     return 

def func2(float1): # The only param must be float 

    if isinstance(float1, float): 
     # ...function code... 
     pass 
    else: 
     return 

def func3(str1): # string 
    if isinstance(str1, str): 
     # ...function code... 
     print 'fdfd' 
     pass 
    else: 
     return 


# and, so on ... 

그러나 각 기능에 대해 모듈 수준에서 수행하고 싶지 않습니다. 각 함수는 다른 인수를 가질 수 있습니다. 이것은 함수 오버로딩이 아닙니다. 데코레이터 나 메타 클래스를 쓰려고 생각 중이었습니다. 여기에 내가 두 접근 방법에 직면하고있는 문제입니다 : -

  1. 를 모든 기능에 대한 일반적인 장식을 사용 :이 방법
    는, 정말 폐기, 각 함수 내에서 정의 된 실제 변수에 액세스 할 수 없습니다입니다 이 아이디어. 여기 폐쇄 (장식으로 사용되는) 내가 쓸 계획이라고 있습니다 :
def dec(funcName): 
    def typeChecker(): 
     i = __import__(__name__) 
     for m in map(lambda x: i.__getattribute__(x), dir(i)): 
      if '__call__' in dir(m): #Identifying a real function or callable which can be treated as function 
       ## Now, that the function is identified, what should I do here to type-check the arguments?? 
    return typeChecker 

내가이 일을 할 수있는 방법에 관해서는 여기에 몇 가지 통찰력을 제공하십시오.

기능
그때, 인수가 다음 메타 클래스를 사용하여 함수로 전송되는 액세스 인수의 각을 검증하고, 할 수 있다면 난 그냥 궁금 해서요 을 만들기위한 메타 클래스를 2.Using, 새로운 클래스를 반환하는 함수 객체를 생성 할 책임이 있습니다. 그러나 그것을하는 방법을 모른다. 이 문제를 해결하는 좋은 방법입니까?

1 아주 좋은 제안 Martijn Peters가주었습니다 - 특수 효과를 사용하려면. 파이썬 2.7에서 우리가 사용할 수있는 것이 있습니까?

+0

내가 장식 맞아야 인수를 이해 해달라고. 데코 레이팅 된 함수의 인수에는 액세스 할 수 있지만 내부 변수에는 액세스 할 수 없습니다. 그럼, 뭐라구? 함수의 인수 또는 지역 변수? –

+0

예. 맞습니다. 나는 처음에는 내적인 주장에 접근 할 수 있다고 생각했다. 그러나 나는 틀 렸습니다. 그래서, 나는 곧 내 초점을 메타 클래스로 옮겼다. – GodMan

+0

나는 메타 클래스로하지 않을 것이다. "마법"을 피하십시오. 의존성 주입을 고려 했습니까? –

답변

-1

내 성향은 다음과 같이 될 것이다 :

class A(object): 
    def func(self, arg): 
     result = self._get_func(arg)(arg) 

    def _get_func(self, arg): 
     # Create and return the appropriate function here. 
     # You have a variety of options, e.g. arg.__class__ (if it exists), 
     # or use a bunch of isinstance checks, etc. 
     # Please bear in mind that this is really unpythonic!! 
     if isinstance(arg, basestring): 
      pass 

당신이 함수를 많이 호출 할 거라면 당신은 당신의 특정 기능을 캐시 원하고 시도 할 수 있도록, 이것은 분명 비효율적이다 먼저 캐시에서 당기기 _get_func 안에 있습니다. 필요에 따라

def _get_func(self, arg): 
    if arg.__class__ in self._cache: # Or whatever 
     return self._cache[arg.__class__] 
    else: 
     pass # Create and return the appropriate function here. 

은 물론 당신은 (이것은 아마 명확성을 위해 수업을 선호하는 거라고하지만, 모듈 수준 또는 클래스 수준에서 작동한다고)을 _get_func 방법을 대체 할 수 있습니다.

또한 이것이 실제로 만족스럽지 않음을 언급 할 가치가 있습니다. 일반적으로 함수 생성자 내부에 숨기지 않고 다른 기능을 수행해야하는 경우 별도의 함수를 작성하는 것이 훨씬 깔끔합니다. 아니면 적어도 "용서를 구하는 것이 더 낫습니다"라고 말하고 try/except 블록을 사용하여 특정 유형/클래스에만 적용되는 작업을 캡슐화하십시오. 또는이 문서 문자열에 일부 마크 업을 사용하여 일부 주석을 사용할 수 있습니다 - 파이썬 2에서 당신이 각 매개 변수 유형에 주석을 명시 적으로 각 기능을 장식해야 할 것 - 실내 장식을 통해 이렇게

+0

여기서 각 인수에 대한 유효성 검사/입력 확인 방법을 설명해주십시오. – GodMan

1

은 매우 간단합니다 을 호출하고 모듈의 모든 객체를 반복하는 모듈의 바닥에 호출을 배치하고 각 함수 에 데코레이터를 적용합니다.

from functools import wraps 
from itertools import count 

def typechecker(*types, **kw_types): 
    def decorator(func): 
     @wraps(func) 
     def wrapper(*args, **kw): 
      for position, type_, arg in zip(count(), types, args): 
       if not isinstance(arg, type_): 
        raise TypeError("Argument in position %s should be a %s" 
            % (position, type_)) 
      for key, type_ in kw_types.items(): 
       if key in kw_types and not isinstance(kw[key], type_): 
        raise TypeError("Argument %s should be a %s" 
            % (key, type_)) 
      return func(*args, **kw) 
     return wrapper 
    return decorator 

을 그리고 당신은이 같은 작업을 볼 수 있습니다 :

두 경우 모두이 같은 장식은 충분할 수

>>> @typechecker(int, int) 
... def mysum(a,b): 
... return a + b 
... 
>>> mysum(2,3) 
5 
>>> mysum(2.0,3) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 8, in wrapper 
TypeError: Argument in position 0 should be a <type 'int'> 
>>> 
관련 문제