복붙노트

[PYTHON] 자기 .__ dict __. 업데이트 (** kwargs) 좋은 스타일이나 가난한 스타일?

PYTHON

자기 .__ dict __. 업데이트 (** kwargs) 좋은 스타일이나 가난한 스타일?

파이썬에서 Shape에서 상속받은 클래스 인 Circle이 있다고 가정 해 보겠습니다. Shape에는 x 좌표와 y 좌표가 필요하며 Circle에는 반경이 필요합니다. 나는 서클을 초기화 할 수 있기를 원한다.

c = Circle(x=1., y=5., r=3.)

원은 도형을 상속하므로 다른 클래스에는 다른 생성자가 필요하기 때문에 __init__에 명명 된 인수를 사용해야합니다. 수동으로 x, y 및 r을 설정할 수 있습니다.

class Shape(object):
    def __init__(self, **kwargs):
        self.x = kwargs['x']
        self.y = kwargs['y']

class Circle(Shape):
    def __init__(self, **kwargs):
        super(Circle, self).__init__(**kwargs)
        self.r = kwargs['r']

또는 self .__ dict __을 사용하여 내 서클의 속성을 자동으로 설정할 수 있습니다. update (kwargs)

class Shape(object):
    def __init__(self, **kwargs):
        self.__dict__.update(**kwargs)

class Circle(Shape):
    def __init__(self, **kwargs):
        super(Circle, self).__init__(**kwargs)

이것의 장점은 코드가 적고 self.foo = kwargs [ 'foo']와 같은 상용구를 유지할 필요가 없다는 것입니다. 단점은 Circle에 필요한 인수가 명확하지 않다는 점입니다. 이것은 속임수로 간주되거나 좋은 스타일입니까 (서클에 대한 인터페이스가 잘 문서화되어있는 한)?

감사합니다 모두들 사려 깊은 반응을 보였습니다. self .__ dict __. update (** kwargs) hack은 내 코드 구성을 실험하는 데 유용했지만, 명시 적으로 인수를 명시 적으로 전달하고 프로덕션 코드에서 명확한 오류 검사를 수행하여이를 대체해야합니다.

해결법

  1. ==============================

    1.

    class Shape(object):
        def __init__(self, x=None, y=None):
            self.x = x
            self.y = y
    
    class Circle(Shape):
        def __init__(self, r=None, **kwargs):
            super(Circle, self).__init__(**kwargs)
            self.r = r
    

    그리고 이것이 바로 그 것이다. ** kwargs는 실제로 필요하지 않을 때 사용하지 마십시오.

    간단하고 이해하기 쉬운 코드와 두통 코드 + 좋은 docstrings을 작성할 수있는 선택권이있을 때 실제로 선택 사항이 없으면 간단하고 자체적으로 문서화 된 코드를 작성합니다.

  2. ==============================

    2.나는 explicit가 암묵적인 것보다 낫기 때문에 첫 번째 방법이 분명히 바람직하다고 말할 것이다.

    나는 explicit가 암묵적인 것보다 낫기 때문에 첫 번째 방법이 분명히 바람직하다고 말할 것이다.

    Circle (x = 1., y = 5., rr = 3.)과 같은 Circle을 초기화 할 때 오타를 만들면 어떻게 될지 생각해보십시오. __dict __. update (kwargs)에서 발생하지 않는 즉시이 오류를보고 싶습니다.

  3. ==============================

    3.자동으로 할당하려면 다음 방법을 제안하십시오.

    자동으로 할당하려면 다음 방법을 제안하십시오.

    def __init__(self, **kwargs):
        for key, value in kwargs.iteritems():
            setattr(self, key, value)
    

    스타일 측면에서 보면 명시 적으로 작성하고 self .__ dict__를 사용하여 직접 해킹하는 것 사이에 있습니다.

  4. ==============================

    4.Circle .__ init__이 인수에 대해 몇 가지 온 전성 검사를 수행하도록하는 것이 더 분명하기를 원한다면. 아마도 모든 인수가 있는지 확인하고 무의미한 인수에 대해 오류를 발생시킬 수 있습니다.

    Circle .__ init__이 인수에 대해 몇 가지 온 전성 검사를 수행하도록하는 것이 더 분명하기를 원한다면. 아마도 모든 인수가 있는지 확인하고 무의미한 인수에 대해 오류를 발생시킬 수 있습니다.

    Shape에서 데코레이터 또는 헬퍼 함수를 ​​만들 수도 있습니다. 이 같은:

    class Circle(Shape):
        def __init__(self, **kwargs):
            self.check(kwargs, 'x', 'y', 'r')
            super(Circle, self).__init__(**kwargs)
    

    .check는 Shape에서 구현 될 것이고 기본적으로 모든 인수가 kwargs에 있고, 아마도 여분의 인수가 없다는 것을 검증 할 것입니다. (미안, 그 코드가 없습니다 - 당신 스스로 알아낼 수 있습니다). 하위 클래스에서 다른 인수와 다르게 처리 할 수있는 선택적 인수 (예 : Shape .__ init__에 할당되지 않은 기본값을 지정)를 검사하도록 오버로드 할 수도 있습니다.

    그렇지 않으면 인터페이스를 문서화하고 문서화 된 방식대로 작동하면 항상 괜찮습니다. 당신이 그것을 "기대하는"방식으로 작동하게 만드는 다른 방법 (잘못된 인수에 대한 예외를 던지기)은 보너스입니다.

  5. from https://stackoverflow.com/questions/9728243/is-self-dict-updatekwargs-good-or-poor-style by cc-by-sa and MIT license