Selon mon commentaire sur la réponse de @ Mark, j'aime l'approche d'usine qu'il préconise. Cependant, je ne le ferais pas exactement comme il le veut, parce qu'il refait une nouvelle classe à chaque fois. , Cela est plutôt un beau cas d'utilisation pour mixin MI et super
, comme suit:
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())()
etc.
Maintenant, les alternatives sont possibles, comme un objet Python peut changer son propre __class__
, et ainsi de suite. Cependant, comme tirer des mouches avec un fusil de rhinocéros, en utilisant une force excessive (extrêmement puissant, profond, et des fonctions linguistiques quasi-magiques) pour résoudre des problèmes qui peuvent être résolus avec une retenue raisonnable (l'équivalent d'un flyswatter), n'est PAS recommandé;).
Modifier: l'injection supplémentaire de object
dans les bases est nécessaire que pour compenser le fait que triste en Python 2. * la classe HTTPConnection est ancienne et ne joue donc pas bien avec les autres - témoin ...:
>>> 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'>]
>>>
l'ordre méthode résolution (alias MRO) dans la classe Y (sans injection supplémentaire d'une base object
) a objet avant la classe de httplib (si super
ne fait pas la bonne chose), mais l'injection supplémentaire perturbe le MRO pour compenser. Hélas, un tel soin est nécessaire dans Python 2. * lorsqu'il s'agit de mauvaises vieilles classes de style hérité; heureusement, en Python 3, le style hérité a disparu et chaque classe "joue bien avec les autres" comme il se doit! -)
Merci. Encore quelque chose que je ne connaissais pas "super". Cela m'évite d'indenter tout mon fichier pour l'inclure dans le code de l'usine. Utilisera ceci. – pkit
@pkit, toujours heureux de vous aider! «super» doit toujours être utilisé avec précaution, mais pour ce cas inhabituel de mixins nécessitant des «initiés» spécialisés, c'est vraiment un bon choix. –
Lorsque j'utilise ceci, il semble que la connexion HTTP (S) .__ init__ ne soit pas appelée. Se pourrait-il que je manque quelque chose dans cette configuration de classe? – pkit