2009-08-15 9 views
1

httplib.HTTPSConnectionから継承するクラスがあります。httplib.HTTP(s)接続から継承する際のSSLと非SSLの両方の接続の処理

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

それは私も非セキュアサーバーと通信するためにそれを使用することができますので、クラスがinstantiatiedされたときにSSL層をオフにすることは可能ですか?

私SSLはそう別のソリューションを使用する必要がある場合には、初期化する前に知られている私の場合はhttplib.HTTPSConnectionからの継承を切り替えるしようとするだろうhttplib.HTTPConnection、私もやる方法がわからないですこれは賢明な方法でですか?

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() 

出力:あなたは工場出荷時のパターンのようなものを使用することができますPythonであなたの最後の段落毎の

答えて

1

@ Markの答えに対する私のコメントとして、私は彼が主張している工場のアプローチが好きです。しかし、毎回新しいクラスを作り直すので、私は彼のやり方を正確にはしません。むしろ、これは次のように、MIをミックスインしてsuperのための素敵なユースケースです:Pythonのオブジェクトは等々__class__、独自の変更、およびすることができますので、今、代替手段は可能であるが、

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())() 

など

。しかし、ライノライフルを使って飛ぶ飛行機のように、過度の力(非常に強力な、深い、魔法のような言語機能)を使用して、合理的な拘束(フライスバータと同等)でうまく解決できる問題を解決することはお勧めしません。 )。

編集:拠点におけるobjectの余分な注入が唯一のPython 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'>] 
>>> 

メソッド解決順序(objectベースのさらなる注入なし)クラスY中(別名MRO)はhttplibからクラスの前にオブジェクトをしている(そうsuperは正しいことをしません)、余分な注入がMROを揺らして補償する。ああ、そのような注意は、Python 2で必要とされます。*悪い古いレガシースタイルのクラスを扱うとき。幸いなことに、Python 3では、従来のスタイルは消えており、すべてのクラスは他の人とうまくやります。 - )

+0

ありがとうございます。もう一度私は「スーパー」を知らなかった。これにより、ファイル全体をインデントしてファクトリコードで囲む必要がなくなります。これを使用します。 – pkit

+1

@pkit、常に喜んで助けてください! 'super'は常にcfr http://fuhm.net/super-harmful/を注意深く使用する必要がありますが、特殊な' __init__'を必要とするmixinのこのような例外的なケースのためには、本当にぴったりです。 –

+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、ファクトリーアプローチは唯一の方法ではありません - それは単にファーストベスト、きれいで、直接的で、完璧な方法です。私はマークと同じようにはしませんでした(これは多くの別々のしかし同じクラスを生成します)が、私は一般的な理由で+1です。 –

+0

@Alex、ご返信ありがとうございます。 httplibコードを見ると、connectメソッドだけが再実装されているようです。 HTTPConnectionを使用してHTTPSConnectionインスタンスにパッチを適用しますか。接続方法は意味がありますか?またはこれはちょうど普通の醜いですか? – pkit

0

は、あなたが別のホストに複数の後続の接続のためのMyConnectionとを使用したいです。その場合、HTTP(S)Connectionから継承するべきではありません。そのクラスは、実際に複数の接続に使用されることはありません。代わりに、MyContnection にHTTP(S)接続があるようにしてください。

+0

私の場合、実際には1つのホストへの1つの接続のためだけに使用します。だから私はそれがSLLかwihtoutでなければならないのかどうかを知るのです。 – pkit

関連する問題