L'appel de type(x) sur un objet x renvoie le type de cet objet. L'appel de type(type(...type(x)...)) finit toujours par produire type lui-même, type(type) = type étant un point fixe. L'exemple le plus complexe que j'ai pu trouver était

class Meta(type):
    pass

class C(metaclass=Meta):
    pass

x = C()

Qui nécessite trois appels à taper (type(type(type(x)))) pour évaluer en type.

Est-il vrai pour toute expression en Python, qu'au plus trois appels à type sont nécessaires pour atteindre le point fixe? Sinon, y a-t-il une limite finie (juste supérieure à trois) ou la pile requise d'appels type peut-elle augmenter indéfiniment?

-1
Andreas T 17 sept. 2020 à 11:11

2 réponses

Meilleure réponse

La pile requise d'appels type peut croître indéfiniment.

Voici un exemple:

>>> class Meta(type):
...     pass
... 
>>> class C(type, metaclass=Meta):
...     pass
... 
>>> class D(type, metaclass=C):
...     pass
... 
>>> class E(type, metaclass=D):
...     pass
... 
>>> class F(type, metaclass=E):
...     pass
... 
>>> f = F("1",(),{});
>>> type(f)
<class '__main__.F'>
>>> type(type(f))
<class '__main__.E'>
>>> type(type(type(f)))
<class '__main__.D'>
>>> type(type(type(type(f))))
<class '__main__.C'>
>>> type(type(type(type(type(f)))))
<class '__main__.Meta'>
>>> type(type(type(type(type(type(f))))))
<class 'type'>
>>> type(type(type(type(type(type(type(f)))))))
<class 'type'>
>>> 

4
Kristian 17 sept. 2020 à 08:18

Le cas type(type) == type est simplement le cas de base des types instanciables. Tout comme la première couche de types peut être créée à partir de type, d'autres couches peuvent être construites. Il n'y a pas de limite fixe.

def descend(base=type):
    while True:
        class base(base, metaclass=base):
            pass
        yield base

def type_depth(tp):
    depth = 0
    while type(tp) != type:
          depth += 1
          tp = type(tp)
    return depth

for tp in descend():
    print(tp, type_depth(tp))

En pratique, il y a une limite pour l ' utilité des méta-couches: la plupart des classes sont des instances directes de type lui-même ou de l'un de ses sous-types.

1
MisterMiyagi 17 sept. 2020 à 08:39