我有一个继承自httplib.httpsconnection的类。

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

当类被实例化时,是否可以关闭ssl层,以便我也可以使用它与非安全服务器通信?
我的情况是,在初始化之前就知道是否应该使用ssl,所以另一个解决方案是尝试将继承从httplib.httpsconnection切换到httplib.httpconnection,但我也不确定如何以合理的方式来这样做?

最佳答案

根据我对@mark回答的评论,我喜欢他提倡的工厂方法。但是,我不会完全按照他的方式去做,因为他每次都会重新上一节课。更确切地说,这是Mixin 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())()

等。
现在,替代方案是可能的,因为python对象可以改变自己的__class__,等等。然而,就像用犀牛步枪射击苍蝇一样,使用过度的力量(极其强大、深邃、近乎神奇的语言特征)来解决那些可以通过合理的约束(相当于苍蝇拍)很好地解决的问题是不被推荐的;-。
编辑:只需要在基中额外注入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'>]
>>>

类y中的方法解析顺序(aka mro)(不需要进一步注入object基)在来自httplib的类之前有object(所以super没有做正确的事情),但是额外的注入会使mro抖动以进行补偿。唉,在Python2中需要这样的关注。*当处理旧的遗留样式类时;幸运的是,在Python3中,遗留样式已经消失了,每个类都应该“与其他类配合良好”!-)

10-08 10:53