2011-10-28 3 views
3

나는 현재 파이썬의 API 라이브러리를 쓰고 있어요 다음과 같은 코드가 너무 unpythonic 있는지 궁금 해요 :하지 목록에있는 kwargs로가 전달되는 경우 accepts 장식이 오류가 발생합니다반복적 인 코드를 방지하기 위해 ** kwargs와 데코레이터를 사용할 수 있습니까?

@accepts('video_id', 'reference_id', 'page_size', 'page_number', 
     'get_item_count', 'fields', 'video_fields', 'custom_fields', 
     'media_delivery', 'output') 
@requires('video_id', 'reference_id') 
def find_related_videos(self, **params): 
    return ItemCollection(read_request(params)) 

방법. 또한 특정 키워드에 대한 유효성 검사를 수행합니다.

장식자 requires 데코레이터는 이러한 키워드 인수가 있는지 확인합니다.

메서드 정의에 args 키워드가 없으므로 저를 괴롭 히고 있습니다. 그러나 각 방법에 대해 params 사전을 수동으로 작성해야하는 것은 짜증이납니다. 또한 메서드에 전달 된 video_fields 인수의 모든 인스턴스에 대해 동일한 유효성 검사 코드가 있으므로 반복을 피하기 위해 데코레이터에서 호출 할 수 있습니다.

생각하십니까?

답변

1

I 좋겠 확실히 메소드 서명에 필요한 필드를 넣어 :

def find_related_videos(self, video_id, reference_id, **params): 
    params.update({'video_id': video_id, 'reference_id': reference_id}) 
    return ItemCollection(read_request(params)) 

가능하면, 심지어뿐만 아니라 키워드 인수를 위해 read_request을 수정할 것 :

def find_related_videos(self, video_id, reference_id, **params): 
    return ItemCollection(read_request(video_id=video_id, reference_id=reference_id, **params)) 

를 아득히 받아 들일 수있는 매개 변수는 개인적으로 잘못된 매개 변수에 대한 오류를 던지지 않을 것입니다. 필요하지 않은 매개 변수는 무시했을 것입니다.

+1

여기에 약간의 문제가 있다는 것을 알고 있습니다.하지만 호출자가 변수를 전달하면 호출자는 해당 변수가 중요 할 것으로 예상하고 호출자가 무시해야 할 것으로 예상하지 않을 수 있습니다. 이것은 예기치 않은 결과를 초래할 수 있으며 이는 좋은 일이 아닙니다. 필자는 일반적으로 오류를 던지고 프로그래머가 매개 변수를 무시하고 프로그래머를 놀라게하는 것보다 중요한 것을 보는 것이 더 좋습니다. – TimothyAWiseman

0

데코레이터가 없으면 할 것입니다.

required = set(['video_id', 'reference_id']) 
acceptable = required.union(set(['page_size', 'page_number', 'get_item_count', 'fields', 'video_fields', 'custom_fields', 'media_delivery', 'output'])) 

def find_related_videos(self, **params): 
    if not (required.issubset(set(params.keys())) or set(params.keys()).issubset(acceptable)): 
     raise Exception("Some exception") 
    return ItemCollection(read_request(params)) 

이 모든 kwargs로 '키가 acceptable 세트에 있고 적어도 required 인수가 있는지 확인합니다 : 독자가 장식없이 코드 executation 경로를 따라하기가 훨씬 쉽습니다.

1

이 솔루션은 어떻습니까?

def check_params(params): 
    # Do whatever check you want to do on params 
    return dict((k, v) for k, v in params 
       if v is not None and k != "self") 

def find_related_videos(self, video_id, reference_id, page_size=None, 
         page_number=None, get_item_count=None, fields=None, 
         video_fields=None, custom_fields=None, 
         media_delivery=None, output=None): 
    params = check_prams(locals()) 
    return ItemCollection(read_request(params)) 

check_params() 사용자 정의 테스트를 facitlitating 동안, 파이썬 허용하고 필요한 매개 변수를 확인 떠날 것이다.

0

이 작업을 수행하는 경우 :

def find_related_videos(self, video_id, reference_id, ...) 

후 여전히 인수의 유효성을 확인하기 위해 장식을 사용하고, 당신을 위해 나머지를 적용 할 인터프리터를 떠날 수 있습니다. 그래도 약간의 단점이 있습니다.

  • 위치 지정 인수를 사용하면 더 이상 호출자가 임의의 순서로 인수를 지정할 수 없습니다. 기본적으로 사전을 읽고 통과하는 경우 문제가 될 수 있습니다.
  • 그것은 같은 일반적인 방법으로 인수의 유효성을 확인하는 당신의 @accepts (또는 @validate) 장식을 쓰기 어렵습니다. 그것은 여전히 ​​inspect.getargspec 기능을 사용하여 수행 할 수 있고, 내가 전에 비슷한 일을했지만, 그것은 당신에게 작업을 얻기 위해 약간의 시간이 걸릴 수 있습니다. HTTP GET 매개 변수를 함수 인수에 자동으로 일치시키는 내 데코레이터는 복잡하지만 작동합니다.
관련 문제