web-dev-qa-db-fra.com

Pourquoi une fonction importée "sous" un autre nom conserve-t-elle son nom d'origine __name__?

Ici:

from os.path import exists as foo
print foo.__name__

nous obtenons: 'exists'. Pourquoi pas 'foo'? Quel attribut donnerait 'foo'?

18
Basj

Vous pouvez voir import foo as bar comme une simple cession. Vous ne vous attendriez pas à ce qu'une fonction modifie son attribut __name__ lorsque vous attribuez un autre nom à la fonction.

>>> def foo(): pass
>>> 
>>> foo.__name__
'foo'
>>> bar = foo
>>> bar.__name__
'foo'

Merci. Quel attribut de la variable bar renverrait alors la chaîne 'bar'?

Il n'y a pas un tel attribut. Les noms (bar) font référence aux valeurs (l'objet fonction) de manière unidirectionnelle.

L'attribut __name__ d'une fonction est défini comme le nom avec lequel la fonction a été définie à l'aide de
def ... syntaxe. C'est pourquoi vous n'obtenez pas d'attribut significatif __name__ si vous définissez une fonction anonyme et affectez le nom foo après sa création.

>>> foo = lambda: None
>>> foo.__name__
'<lambda>'
35
timgeb

L'importation d'un objet lie simplement une nouvelle variable, et l'ajout de as newname ne vous permet que de choisir un autre nom à utiliser pour la variable dans l'espace de nom actuel.

L'attribut __name__ sur un objet ne dit rien sur le nom auquel il est lié, vous pouvez avoir autant de variables que de conteneurs, tels que des listes ou des dictionnaires pointant sur le même objet, après tout:

def foo(): pass

bar = foo
spam = foo
list_of_functions = [foo]
dictionary_of_functions = {'monty': foo, 'python': foo}

Ce qui précède a créé 4 références supplémentaires à l’objet fonction; vous ne pouvez pas avoir foo.__name__ refléter tout cela, et les références dans list_of_functions et dictionary_of_functions n'ont pas (directement) de noms.

Étant donné que import foo, import bar as foo, from module import foo et from module import bar as foo ont tous juste pour objet de définir le nom foo dans le module actuel, ils sont traités exactement de la même manière que les autres assignations. Vous pouvez également importer la fonction plusieurs fois, sous différents noms.

Au lieu de cela, la valeur __name__ d'une fonction est définie sur le nom avec lequel elle a été définie dans l'instruction def <name>(...):. C'est une aide au débogage, tout au plus. Il est utilisé dans les retraits, par exemple, pour faciliter l'identification des lignes de code affichées dans le retraçage. Vous ne définissez le __name__ sur quelque chose d'autre si cela peut aider à mieux identifier l'emplacement. (Remarque: dans Python 3, il existe également l'attribut __qualname_ , qui est utilisé à la place de __name__ car il inclut davantage d'informations sur l'emplacement de la fonction lorsqu'elle est imbriquée ou définie dans une classe).

16
Martijn Pieters

as est un sucre syntaxique dans le fichier/la session d'importation, tandis que l'attribut __name__ fait partie de l'objet fonction.

0
halloleo