2014-06-13 6 views
3

Je supposais que tuple(tuple_instance) devrait (en tant qu'optimisation) être capable de retourner le tuple d'entrée sans faire une copie. Il se trouve que sur cette CPython semble être le cas:tuple identité lors de l'appel de tuple sur un tuple

>>> t = ('foo', 'bar', 'baz') 
>>> v = tuple(t) 
>>> v is t 
True 

bien jusqu'à présent. Cependant, en parcourant la source, je vois qu'il ya PyTuple_MAXSAVESIZE qui pourrait venir jouer ici. Essayons pour des tuples plus grands:

>>> t = ('foo', 'bar', 'baz') * 100 
>>> v = tuple(t) 
>>> v is t 
True 

Et cela semble fonctionner aussi.

Ma question principale est de savoir si ce comportement est toujours le cas dans CPython. J'ai regardé PyTuple_New, mais je ne vois rien là qui puisse expliquer ce que je vois ici, donc ce comportement doit être défini ailleurs (ou je l'ai manqué ... mon C est assez atrophié à ce stade .. .).

+2

Quelques instants @mglison pose réellement une question :) +1 –

+0

['tuple_new'] (http://hg.python.org/cpython/file/55fed3eae14b/Objects/tupleobject.c#l644) est ce qu'on appelle quand vous faites 'tuple (t)', et cela finit par appeler 'PySequence_Tuple' sur l'argument. 'PySequence_Tuple' retourne probablement son argument si l'argument est un tuple, mais je ne trouve pas la source pour cette fonction. – user2357112

+0

Cela ressemble à la source de 'PySequence_Tuple': https://github.com/python/cpython/blob/10dccd220ea2f45bd4b7eba3d7766d7c0a4646ad/Objects/abstract.c#L1660 – senshin

Répondre

2

Bon, la séquence d'appel est le suivant:

tuple_new appels PySequence_Tuple à la fin. PySequence_Tuple a l'optimisation construit que si elle est un tuple (pas une sous-classe de tuple), il retourne juste tuple (voir la ligne avec PyTuple_CheckExact qui est en fait un macro ...)

SO, en résumé, actuellement (CPython2 .7.7) l'appel tuple sur une instance de tuple retournera l'instance d'entrée si le type d'entrée ligne esttuple. Les sous-classes de tuple seront copiées.

Il semble également y avoir un chemin optimisé pour les listes. Cela pourrait couvrir également les sous-classes tuple, mais je n'ai pas creusé aussi loin.