2009-08-15 2 views
1

httplib.HTTPSConnection에서 상속하는 클래스가 있습니다.httplib.HTTP (s) 연결을 상속 할 때 SSL 및 비 SSL 연결을 모두 처리합니다.

class MyConnection(httplib.HTTPSConnection): 
    def __init__(self, *args, **kw): 
    httplib.HTTPSConnection.__init__(self,*args, **kw) 
    ... 

클래스가 인스턴스화 될 때 SSL 계층을 해제하여 비보안 서버와 통신 할 수 있습니까?

SSL 그래서 다른 해결책이 httplib.HTTPConnectionhttplib.HTTPSConnection에서 상속을 전환하려고하는 것입니다 사용해야하지만, 나 또한 할 방법을 잘 모르겠습니다 경우는 초기화하기 전에 알려진 나는 내 경우

이것은 현명한 방법으로?

class Foo: 
    def doit(self): 
     print "I'm a foo" 
class Bar: 
    def doit(self): 
     print "I'm a bar" 

def MakeClass(isSecure): 
    if isSecure: 
     base = Foo 
    else: 
     base = Bar 

    class Quux(base): 
     def __init__(self): 
      print "I am derived from", base 

    return Quux() 

MakeClass(True).doit() 
MakeClass(False).doit() 

출력 : 당신이 공장 패턴 같은 것을 사용할 수 있습니다 파이썬에서 마지막 단락 당

답변

1

@ Mark의 대답에 대한 내 의견에 따르면, 나는 그가 옹호하는 공장 접근법을 좋아합니다. 그러나 매번 새로운 수업을 새로 시작하기 때문에 나는 그의 방식대로하지 않을 것입니다. 다음과 같이 오히려,이 MI 및 super을 믹스 인을위한 좋은 사용 사례입니다 :

class MyConnectionPlugin(object): 
    def __init__(self, *args, **kw): 
    super(MyConnectionPlugin, self).__init__(*args, **kw) 
    # etc etc -- rest of initiatizations, other methods 

class SecureConnection(MyConnectionPlugin, 
         httplib.HTTPSConnection, object): 
    pass 

class PlainConnection(MyConnectionPlugin, 
         httplib.HTTPConnection, object): 
    pass 

def ConnectionClass(secure): 
    if secure: 
    return SecureConnection 
    else: 
    return PlainConnection 

conn = ConnectionClass(whatever_expression())() 

파이썬 객체 등 __class__ 자체를 변경 할 수 있기 때문에 이제 대안이 가능하다. 그러나 라이노 라이플로 총을 쏘는 것과 같이 합리적인 제한 (flyswatter와 동등)으로 해결할 수있는 문제를 해결하기 위해 과도한 힘 (매우 강력하고 심오하며 거의 마법 같은 언어 기능)을 사용하는 것은 권장하지 않습니다.).

편집 : 기지에서 object의 추가 주입은 파이썬 2. *에 HttpConnection에 클래스가 다른 사람들과 잘 재생되지 않습니다 때문에 이전 스타일이고 있다는 슬픈 사실을 보상하기 위해에만 필요합니다 - 증거 ... :

>>> import httplib 
>>> class Z(object): pass 
... 
>>> class Y(Z, httplib.HTTPConnection): pass 
... 
>>> Y.mro() 
[<class '__main__.Y'>, <class '__main__.Z'>, <type 'object'>, <class httplib.HTTPConnection at 0x264ae0>] 
>>> class X(Z, httplib.HTTPConnection, object): pass 
... 
>>> X.mro() 
[<class '__main__.X'>, <class '__main__.Z'>, <class httplib.HTTPConnection at 0x264ae0>, <type 'object'>] 
>>> 

방법-확인 순서 (AN object베이스의 추가 주입없이) 클래스 Y의 (일명 MRO)이 HTTPLIB에서 수업 전에 개체가 (그래서 super는 옳은 일을하지 않습니다), 여분의 주입은 MRO를 흔들어 보정합니다. 슬프게도, 파이썬 2에서는 그러한 치료가 필요합니다. * 오래된 낡은 레거시 스타일의 클래스를 다룰 때; 다행스럽게도 파이썬 3에서는 레거시 스타일이 사라지고 모든 클래스가 "다른 사람들과 잘 어울립니다"- -

+0

감사합니다. 또 다시 나는 '슈퍼'를 몰랐다. 이렇게하면 공장 코드에서 파일 전체를 들여 쓰지 않아도됩니다. 이것을 사용합니다. – pkit

+1

@pkit, 항상 도와 줘서 기쁩니다! 'super '는 항상 cfr http://fuhm.net/super-harmful/을주의 깊게 사용해야합니다. 그러나 특수한 __init__을 필요로하는 믹스 인의 경우에는 정말 적합합니다. –

+0

이것을 사용할 때 HTTP (S) Connection .__ init__이 호출되지 않은 것처럼 보입니다. 이 수업 준비에서 뭔가를 놓치고있을 수 있습니까? – pkit

2

, 분명히

I am derived from __main__.Foo 
I'm a foo 
I am derived from __main__.Bar 
I'm a bar 
+0

이 통찰력에 감사드립니다. 아직도 이것이 HTTPSConnection을 상속 할 때 두 경우를 모두 처리 할 수있는 유일한 방법인지 궁금합니다. – pkit

+1

@pkit, 공장 접근 방식은 유일한 방법이 아닙니다. 그것은 단순하고 깨끗하며 직접적이고 완벽합니다. Mark와 똑같은 일을하지는 않을 것입니다. (많은 별도의 클래스이지만 동일한 클래스를 생성합니다) 그러나 나는 여전히 일반적인 근거로 +1합니다. –

+0

@Alex, 귀하의 회신에 감사드립니다. httplib 코드를 보면 connect 메소드 만 다시 구현 된 것처럼 보입니다. 원숭이가 HTTPConnection을 사용하여 HTTPSConnection 인스턴스를 패치합니다.연결 방법이 합리적입니까? 아니면 그냥 평범한가? – pkit

0

, 당신은 다른 호스트에 여러 이후 연결하고 MyConnection을 사용하려면 . 그렇다면 HTTP (S) Connection을 전혀 상속하지 않아야합니다.이 클래스는 실제로 여러 연결에 사용되지 않습니다. 대신 MyConnection 을 HTTP (S) 연결로 설정하십시오.

+0

제 경우에는 실제로 하나의 호스트에 대해 하나의 연결에만 사용합니다. 그것이 내가 SLL 또는 wihtout과 함께 있어야하는지 instatiation 전에 알아 이유입니다. – pkit