Dans la plupart bien connus des langages à objets, une expression comme SomeClass(arg1, arg2)
attribuera une nouvelle instance, l'initialisation de l'instance attributs, puis le retourner.
Dans la plupart bien connus des langages à objets, l'initialisation de l'instance attributs" partie peut être personnalisé pour chaque classe par la définition d'un constructeur, qui est fondamentalement juste un bloc de code qui fonctionne sur la nouvelle instance (à l'aide des arguments fournis par le constructeur de l'expression) pour mettre en place quelles que soient les conditions initiales sont souhaitées. En Python, ce qui correspond à la classe' __init__
méthode.
Python __new__
n'est rien de plus et rien de moins que les autres par classe de personnalisation de la "allouer une nouvelle instance de la partie". Bien sûr, cela vous permet de faire des choses inhabituelles, comme un retour à une instance existante plutôt que d'attribuer un nouveau. Donc en Python, on ne pense pas vraiment que de cette partie comme impliquant nécessairement la répartition; tout ce que nous demandons, c'est qu' __new__
vient avec un exemple de quelque part.
Mais il est encore seulement la moitié du travail, et il n'y a aucun moyen pour le Python système de savoir que, parfois, vous voulez exécuter l'autre moitié de l'emploi (__init__
) par la suite et parfois vous n'en avez pas. Si vous voulez que le comportement, vous avez le dire explicitement.
Souvent, vous pouvez restructurer donc, vous avez seulement besoin d' __new__
, ou si vous n'avez pas besoin d' __new__
, ou d' __init__
se comporte différemment sur un déjà-initialisation de l'objet. Mais si vous voulez vraiment, Python n'effectivement vous permettre de redéfinir "le travail", de sorte qu' SomeClass(arg1, arg2)
n'est pas forcément __new__
suivie par __init__
. Pour ce faire, vous devez créer une métaclasse, et de définir ses __call__
méthode.
Une métaclasse est juste la classe d'une classe. Et une classe' __call__
méthode contrôle ce qui se produit lorsque vous appelez les instances de la classe. Ainsi, une métaclasse' __call__
méthode contrôle ce qui se produit lorsque vous appelez une classe; c'est à dire qu'il permet de redéfinir l'instance-mécanisme de création du début à la fin. C'est le niveau à partir duquel vous pouvez plus élégamment mettre en œuvre entièrement non-standard de la création de l'instance de processus tels que le pattern singleton. En fait, avec moins de 10 lignes de code que vous pouvez mettre en œuvre un Singleton
métaclasse qui, ensuite, n'a même pas besoin de vous futz avec __new__
à tous, et peut tourner tout autrement-classe normale dans un singleton par le simple ajout d' __metaclass__ = Singleton
!
class Singleton(type):
def __init__(self, *args, **kwargs):
super(Singleton, self).__init__(*args, **kwargs)
self.__instance = None
def __call__(self, *args, **kwargs):
if self.__instance is None:
self.__instance = super(Singleton, self).__call__(*args, **kwargs)
return self.__instance
Cependant, c'est probablement plus profond de la magie que ce qui est vraiment garanti pour cette situation!