문제

오늘 오후에 나는 몇 시간 동안 내 맞춤형 확장에서 버그를 찾기 위해 urllib2.Request. 문제는 내가 알게 된 바와 같이 super(ExtendedRequest, self), 부터 urllib2.Request (나는 Python 2.5에 있습니다) 여전히 구식 클래스입니다. super() 불가능합니다.

두 기능을 모두 갖춘 새로운 클래스를 만드는 가장 분명한 방법.

class ExtendedRequest(object, urllib2.Request):
    def __init__():
        super(ExtendedRequest, self).__init__(...)

작동하지 않습니다. 그것을 부르면서 나는 남았다 AttributeError: type 자란 urllib2.Request.__getattr__(). 이제 시작하고 복사하기 전에 전체를 붙여 넣습니다. urllib2.Request /usr/lib/python에서 클래스를 다시 작성하려면

class Request(object):

내가 어떻게 더 우아한 방식으로 이것을 달성 할 수 있는지 아이디어가 있습니까? (와 함께 이것 a 새로운 스타일 수업을 기반으로합니다 urllib2.Request 작업 지원과 함께 super().)

편집하다: 그건 그렇고 : AttributeError가 언급했습니다.

>>> class ExtendedRequest(object, urllib2.Request):
...   def __init__(self):
...     super(ExtendedRequest, self).__init__('http://stackoverflow.com')
...
>>> ABC = ExtendedRequest ()
>>> d = urllib2.urlopen(ABC)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/urllib2.py", line 124, in urlopen
    return _opener.open(url, data)
  File "/usr/lib/python2.5/urllib2.py", line 373, in open
    protocol = req.get_type()
  File "/usr/lib/python2.5/urllib2.py", line 241, in get_type
    if self.type is None:
  File "/usr/lib/python2.5/urllib2.py", line 218, in __getattr__
    raise AttributeError, attr
AttributeError: type
도움이 되었습니까?

해결책

계층 구조가 간단하기 때문에 이것은 잘 작동합니다

class ExtendedRequest(urllib2.Request):
    def __init__(self,...):
        urllib2.Request.__init__(self,...)

다른 팁

슈퍼를 사용하는 것이 항상 최고의 실습이 아닐 수도 있습니다. Super를 사용하는 데 많은 어려움이 있습니다. James Knight 's를 읽으십시오 http://fuhm.org/super-harmful/ 예를 들어.

그 링크는 (다른 문제들 중에서) 그것을 보여줍니다

  1. 서브 클래스가있는 경우 슈퍼 클래스는 Super를 사용해야합니다
  2. 그만큼 __init__ Super를 사용하는 모든 서브 클래스의 서명이 일치해야합니다. 당신은 당신이받는 모든 인수를 슈퍼 기능에 전달해야합니다. 당신의 __init__ 다른 클래스를 호출 할 준비가되어 있어야합니다 __init__ 계층 구조의 방법.
  3. 위치 인수를 사용하지 마십시오 __init__

귀하의 상황에서 위의 각 기준은 위반됩니다.

제임스 나이트는 또한

Super ()가 실제로 도움이 될 수있는 유일한 상황은 다이아몬드 상속이있을 때입니다. 그리고 그럼에도 불구하고, 그것은 종종 당신이 생각했던 것만 큼 도움이되지 않습니다.

슈퍼를 올바르게 사용할 수있는 조건은 충분히 번거롭고 슈퍼의 유용성이 다소 제한적이라고 생각합니다. 서브 클래싱보다 작곡 설계 패턴을 선호합니다. 가능하다면 다이아몬드 상속을 피하십시오. 상단 (객체)에서 하단까지 객체 계층을 제어하고 슈퍼를 일관되게 사용하면 괜찮습니다. 그러나이 경우 전체 클래스 계층 구조를 제어하지 않으므로 사용하는 것을 포기하는 것이 좋습니다. super.

나는 당신이 자기 매개 변수를 정의로 전달하는 것을 놓친 것 같습니다. 이니 샘플에서. 이거 한번 해봐:

class ExtendedRequest(object, urllib2.Request):
    def __init__(self):
        super(ExtendedRequest, self).__init__(self)

나는 그것을 테스트했고 그것은 OKE를 작동시키는 것 같습니다.

>>> x = ExtendedRequest()
>>> super(ExtendedRequest, x)
<super: <class 'ExtendedRequest'>, <ExtendedRequest object>>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top