2009-11-04 5 views
0

필자에게는 getter 및 setter 메서드가있는 모델 클래스와 때로는 정적 메서드가 있습니다. 유니 코드 문자열을 특정 메서드에 대한 인수로 사용하고 데코레이터를 사용하는 것이 처음 생각이었습니다. 지금은 이런 일이 : 인해 잘못된 인수 개수에메서드에 유니 코드 인수를 적용하는 방법은 무엇입니까?

import types 

class require_unicode(object): 

    def __init__(self, function): 
     self.f = function 

    def __call__(self, string): 
     if not isinstance(string, types.UnicodeType): 
      raise ValueError('String is not unicode') 
     return self.f(string) 

class Foo(object): 

    something = 'bar' 

    @staticmethod 
    @require_unicode 
    def do_another(self, string): 
     return ' '.join(['baz', string]) 

    @require_unicode 
    def set_something(self, string): 
     self.something = string 

foo = Foo() 
foo.set_something('ValueError is raised') 
foo.set_something(u'argument count error') 
foo.do_another('ValueError is raised') 
foo.do_another(u'argument count error') 

위의 코드에서 장식의 __call__ 실패 내부의 메소드 호출을합니다 ('foo는'객체 심판이 없기 때문에?). 바보 같은 짓하기 전에 나는 너희들에게 물어보고 싶었다. 어떻게해야합니까?

답변

1

당신의 문제는 require_unicode 데코레이터가 아닌 @staticmethod 데코레이터에 있다고 생각합니다. 정적 메소드는 클래스 메소드와 달리 클래스에 대한 참조를 첫 번째 인수로받지 않으므로 인수 서명이 잘못되었습니다.

do_another를 @classmethod로 변경하거나 인수에서 self을 제거해야합니다.

편집 :와, 마음은 당신은 - 인스턴스 메소드는 클래스 (자기)의 인스턴스에 대한 참조를받는 동안 classmethod 장식 방법 @, 첫 번째 인수로 클래스을받을 수 있습니다. 그러므로 클래스 메소드 "cls"나 "self"가 아닌 다른 것을 혼동하지 않도록 첫 번째 인수를 명명하는 것이 좋습니다.

0

나는 이것이 좋지 않을 것이라고 생각할 것이다. 당신은 당신의 인자의 타입을 결코 체크하지 말고, 그들이 필요한 메소드와 속성을 가지고 있는지 확인해야한다. 이것을하기위한 가장 간단한 방법은 그들이 거기에 있다고 가정하고 그렇지 않으면 예외를 얻는 것입니다. 그러나 나는 getattr도 할 수 있다고 생각합니다. 을 입력하지 않으면 유형을 확인하십시오.

+0

나는 그것이 unpythonic이지만 인코딩 된 문자열을 방지하면 나중에 주어진 데이터를 데이터베이스에 저장할 때 많은 문제에서 벗어날 수 있습니다. – tuomur

+0

@eclaird : 일단 당신이 절대적으로 긍정적으로 * 유니 코드를 요구하면, 당신이 가지고있는 무엇이든 그것을'unicode()'라고 부르고 그것을 좋게 부르십시오. – Teddy

0

또 다른 옵션은 어설 션을 사용하는 것입니다. 비 유니 코드 유형을 메소드에 전달하는 것이 개발 중에 분명해야하는 프로그래밍 오류로 간주되어야하는지 여부에 달려 있습니다. string 유형 유니 코드이 아닌 때마다

import types 
class Foo: 
    def set_something(self, string): 
     assert isinstance(string, types.UnicodeType), 'String is not unicode' 
     self.something = string 

이 있지만, 파이썬 interpretter은 "deubg"모드에서 실행되는 경우에만 때, AssertionError 예외가 발생합니다. -O 옵션을 사용하여 Python을 실행하면 해석기가 assert를 효율적으로 무시합니다.

+0

당연히, 나는 이것도 생각했다. 그러나 생각한 장식자는 그것을하는 더 깨끗한 방법 일 것이다. – tuomur

+0

그러면 실제로 더 깨끗해 보입니까? IMO 주장은 수표가 메서드의 시작 부분에 바로 있고, 다른 곳에서 가져올 수있는 클래스에 숨겨져 있지 않기 때문에 더욱 분명합니다. 또한'-O'로 파이썬을 실행할 때 어설 션이 사실상 NOP가되는 성능 이점을 얻을 수 있습니다. – mhawke

관련 문제