Why does an imported function “as” another name keep its original __name__?











up vote
13
down vote

favorite
3












Here:



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


we get: 'exists'.
Why not 'foo'? Which attribute would give 'foo'?










share|improve this question


















  • 3




    from X import Y as Z is equivalent to from X import Y; Z=Y; del Y. The only difference is that it does not hide something called Y that already existed before the import and if it existed is not deleted (Y="Hi"; from X import Y as Z then Y == "Hi").
    – Giacomo Alzetta
    Nov 13 at 14:48















up vote
13
down vote

favorite
3












Here:



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


we get: 'exists'.
Why not 'foo'? Which attribute would give 'foo'?










share|improve this question


















  • 3




    from X import Y as Z is equivalent to from X import Y; Z=Y; del Y. The only difference is that it does not hide something called Y that already existed before the import and if it existed is not deleted (Y="Hi"; from X import Y as Z then Y == "Hi").
    – Giacomo Alzetta
    Nov 13 at 14:48













up vote
13
down vote

favorite
3









up vote
13
down vote

favorite
3






3





Here:



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


we get: 'exists'.
Why not 'foo'? Which attribute would give 'foo'?










share|improve this question













Here:



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


we get: 'exists'.
Why not 'foo'? Which attribute would give 'foo'?







python function module python-import






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 13 at 11:56









Basj

5,24528100211




5,24528100211








  • 3




    from X import Y as Z is equivalent to from X import Y; Z=Y; del Y. The only difference is that it does not hide something called Y that already existed before the import and if it existed is not deleted (Y="Hi"; from X import Y as Z then Y == "Hi").
    – Giacomo Alzetta
    Nov 13 at 14:48














  • 3




    from X import Y as Z is equivalent to from X import Y; Z=Y; del Y. The only difference is that it does not hide something called Y that already existed before the import and if it existed is not deleted (Y="Hi"; from X import Y as Z then Y == "Hi").
    – Giacomo Alzetta
    Nov 13 at 14:48








3




3




from X import Y as Z is equivalent to from X import Y; Z=Y; del Y. The only difference is that it does not hide something called Y that already existed before the import and if it existed is not deleted (Y="Hi"; from X import Y as Z then Y == "Hi").
– Giacomo Alzetta
Nov 13 at 14:48




from X import Y as Z is equivalent to from X import Y; Z=Y; del Y. The only difference is that it does not hide something called Y that already existed before the import and if it existed is not deleted (Y="Hi"; from X import Y as Z then Y == "Hi").
– Giacomo Alzetta
Nov 13 at 14:48












3 Answers
3






active

oldest

votes

















up vote
32
down vote



accepted










You can view import foo as bar as just an assignment. You would not expect a function to change its name when you assign another name to it.



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



Thanks. What attribute of the variable bar would return the string 'bar' then?




There is no such attribute. Names (bar) refer to values (the function object) unidirectionally.



The __name__ attribute of a function is set as the name the function was defined with using the
def ... syntax. That's why you don't get a meaningful __name__ attribute if you define an anonymous function and assign the name foo after it has been created.



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





share|improve this answer























  • @Basj there is no such attribute. Names (bar) refer to values (the function) unidirectionally.
    – timgeb
    Nov 13 at 11:59






  • 3




    @Basj It is not strange at all. Python names are just references to memory locations. bar = 'a string', then 'a string' has no clue that it happens to be referenced by bar, so 'a string'.__name__ can never be 'bar'
    – DeepSpace
    Nov 13 at 12:03












  • @DeepSpace Ok. I thought that there would be a duplicate "object" bar that would just make the link to foo, and that would have its proper __name__.
    – Basj
    Nov 13 at 12:05










  • @Basj Note that what you suggest would imply that: 1) the function object has to somehow be modified each time its reference is assigned or unassigned to a new variable name 2) if you assign multiple variable names to the same function reference you would have either make copies of the function or somehow keep track of all the variable names
    – jdehesa
    Nov 13 at 12:05








  • 1




    Another way to see this is that the same function could be referred to by multiple variables. Clearly, it can only have one name. The name is a property of the function, not of the variable.
    – usr
    Nov 13 at 19:27


















up vote
14
down vote













Importing an object just binds a new variable, and all that adding as newname does is let you pick an alternative name to use for the variable in the current namespace.



The __name__ attribute on an object says nothing about the name it is currently bound to, you can have any number of variables as well as containers such as lists or dictionaries pointing to the same object, after all:



def foo(): pass

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


The above created 4 additional references to the function object; you can't have foo.__name__ reflect all of those, and the references in list_of_functions and dictionary_of_functions do not (directly) have names.



Since import foo, import bar as foo, from module import foo and from module import bar as foo all just set the name foo in the current module, they are treated the exact same way as other assignments. You could import the function more than once, under different names, too.



Instead, the __name__ value of a function is set to name it was defined with in the def <name>(...): statement. It is a debugging aid, at most. It is used in tracebacks, for example, to make it easier to identify lines of code shown in the traceback. You'd only set the __name__ to something else if that would help identify the location better. (Note: in Python 3, there is also the __qualname_ attribute, which is used instead of __name__ as it includes more information on where the function is defined when nested or defined on a class).






share|improve this answer






























    up vote
    0
    down vote













    The as is syntactical sugar in the file/session of the import, while the __name__ attribute is part of the function object.






    share|improve this answer





















      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














       

      draft saved


      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53280530%2fwhy-does-an-imported-function-as-another-name-keep-its-original-name%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      32
      down vote



      accepted










      You can view import foo as bar as just an assignment. You would not expect a function to change its name when you assign another name to it.



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



      Thanks. What attribute of the variable bar would return the string 'bar' then?




      There is no such attribute. Names (bar) refer to values (the function object) unidirectionally.



      The __name__ attribute of a function is set as the name the function was defined with using the
      def ... syntax. That's why you don't get a meaningful __name__ attribute if you define an anonymous function and assign the name foo after it has been created.



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





      share|improve this answer























      • @Basj there is no such attribute. Names (bar) refer to values (the function) unidirectionally.
        – timgeb
        Nov 13 at 11:59






      • 3




        @Basj It is not strange at all. Python names are just references to memory locations. bar = 'a string', then 'a string' has no clue that it happens to be referenced by bar, so 'a string'.__name__ can never be 'bar'
        – DeepSpace
        Nov 13 at 12:03












      • @DeepSpace Ok. I thought that there would be a duplicate "object" bar that would just make the link to foo, and that would have its proper __name__.
        – Basj
        Nov 13 at 12:05










      • @Basj Note that what you suggest would imply that: 1) the function object has to somehow be modified each time its reference is assigned or unassigned to a new variable name 2) if you assign multiple variable names to the same function reference you would have either make copies of the function or somehow keep track of all the variable names
        – jdehesa
        Nov 13 at 12:05








      • 1




        Another way to see this is that the same function could be referred to by multiple variables. Clearly, it can only have one name. The name is a property of the function, not of the variable.
        – usr
        Nov 13 at 19:27















      up vote
      32
      down vote



      accepted










      You can view import foo as bar as just an assignment. You would not expect a function to change its name when you assign another name to it.



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



      Thanks. What attribute of the variable bar would return the string 'bar' then?




      There is no such attribute. Names (bar) refer to values (the function object) unidirectionally.



      The __name__ attribute of a function is set as the name the function was defined with using the
      def ... syntax. That's why you don't get a meaningful __name__ attribute if you define an anonymous function and assign the name foo after it has been created.



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





      share|improve this answer























      • @Basj there is no such attribute. Names (bar) refer to values (the function) unidirectionally.
        – timgeb
        Nov 13 at 11:59






      • 3




        @Basj It is not strange at all. Python names are just references to memory locations. bar = 'a string', then 'a string' has no clue that it happens to be referenced by bar, so 'a string'.__name__ can never be 'bar'
        – DeepSpace
        Nov 13 at 12:03












      • @DeepSpace Ok. I thought that there would be a duplicate "object" bar that would just make the link to foo, and that would have its proper __name__.
        – Basj
        Nov 13 at 12:05










      • @Basj Note that what you suggest would imply that: 1) the function object has to somehow be modified each time its reference is assigned or unassigned to a new variable name 2) if you assign multiple variable names to the same function reference you would have either make copies of the function or somehow keep track of all the variable names
        – jdehesa
        Nov 13 at 12:05








      • 1




        Another way to see this is that the same function could be referred to by multiple variables. Clearly, it can only have one name. The name is a property of the function, not of the variable.
        – usr
        Nov 13 at 19:27













      up vote
      32
      down vote



      accepted







      up vote
      32
      down vote



      accepted






      You can view import foo as bar as just an assignment. You would not expect a function to change its name when you assign another name to it.



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



      Thanks. What attribute of the variable bar would return the string 'bar' then?




      There is no such attribute. Names (bar) refer to values (the function object) unidirectionally.



      The __name__ attribute of a function is set as the name the function was defined with using the
      def ... syntax. That's why you don't get a meaningful __name__ attribute if you define an anonymous function and assign the name foo after it has been created.



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





      share|improve this answer














      You can view import foo as bar as just an assignment. You would not expect a function to change its name when you assign another name to it.



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



      Thanks. What attribute of the variable bar would return the string 'bar' then?




      There is no such attribute. Names (bar) refer to values (the function object) unidirectionally.



      The __name__ attribute of a function is set as the name the function was defined with using the
      def ... syntax. That's why you don't get a meaningful __name__ attribute if you define an anonymous function and assign the name foo after it has been created.



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






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 13 at 12:06

























      answered Nov 13 at 11:57









      timgeb

      43.8k106085




      43.8k106085












      • @Basj there is no such attribute. Names (bar) refer to values (the function) unidirectionally.
        – timgeb
        Nov 13 at 11:59






      • 3




        @Basj It is not strange at all. Python names are just references to memory locations. bar = 'a string', then 'a string' has no clue that it happens to be referenced by bar, so 'a string'.__name__ can never be 'bar'
        – DeepSpace
        Nov 13 at 12:03












      • @DeepSpace Ok. I thought that there would be a duplicate "object" bar that would just make the link to foo, and that would have its proper __name__.
        – Basj
        Nov 13 at 12:05










      • @Basj Note that what you suggest would imply that: 1) the function object has to somehow be modified each time its reference is assigned or unassigned to a new variable name 2) if you assign multiple variable names to the same function reference you would have either make copies of the function or somehow keep track of all the variable names
        – jdehesa
        Nov 13 at 12:05








      • 1




        Another way to see this is that the same function could be referred to by multiple variables. Clearly, it can only have one name. The name is a property of the function, not of the variable.
        – usr
        Nov 13 at 19:27


















      • @Basj there is no such attribute. Names (bar) refer to values (the function) unidirectionally.
        – timgeb
        Nov 13 at 11:59






      • 3




        @Basj It is not strange at all. Python names are just references to memory locations. bar = 'a string', then 'a string' has no clue that it happens to be referenced by bar, so 'a string'.__name__ can never be 'bar'
        – DeepSpace
        Nov 13 at 12:03












      • @DeepSpace Ok. I thought that there would be a duplicate "object" bar that would just make the link to foo, and that would have its proper __name__.
        – Basj
        Nov 13 at 12:05










      • @Basj Note that what you suggest would imply that: 1) the function object has to somehow be modified each time its reference is assigned or unassigned to a new variable name 2) if you assign multiple variable names to the same function reference you would have either make copies of the function or somehow keep track of all the variable names
        – jdehesa
        Nov 13 at 12:05








      • 1




        Another way to see this is that the same function could be referred to by multiple variables. Clearly, it can only have one name. The name is a property of the function, not of the variable.
        – usr
        Nov 13 at 19:27
















      @Basj there is no such attribute. Names (bar) refer to values (the function) unidirectionally.
      – timgeb
      Nov 13 at 11:59




      @Basj there is no such attribute. Names (bar) refer to values (the function) unidirectionally.
      – timgeb
      Nov 13 at 11:59




      3




      3




      @Basj It is not strange at all. Python names are just references to memory locations. bar = 'a string', then 'a string' has no clue that it happens to be referenced by bar, so 'a string'.__name__ can never be 'bar'
      – DeepSpace
      Nov 13 at 12:03






      @Basj It is not strange at all. Python names are just references to memory locations. bar = 'a string', then 'a string' has no clue that it happens to be referenced by bar, so 'a string'.__name__ can never be 'bar'
      – DeepSpace
      Nov 13 at 12:03














      @DeepSpace Ok. I thought that there would be a duplicate "object" bar that would just make the link to foo, and that would have its proper __name__.
      – Basj
      Nov 13 at 12:05




      @DeepSpace Ok. I thought that there would be a duplicate "object" bar that would just make the link to foo, and that would have its proper __name__.
      – Basj
      Nov 13 at 12:05












      @Basj Note that what you suggest would imply that: 1) the function object has to somehow be modified each time its reference is assigned or unassigned to a new variable name 2) if you assign multiple variable names to the same function reference you would have either make copies of the function or somehow keep track of all the variable names
      – jdehesa
      Nov 13 at 12:05






      @Basj Note that what you suggest would imply that: 1) the function object has to somehow be modified each time its reference is assigned or unassigned to a new variable name 2) if you assign multiple variable names to the same function reference you would have either make copies of the function or somehow keep track of all the variable names
      – jdehesa
      Nov 13 at 12:05






      1




      1




      Another way to see this is that the same function could be referred to by multiple variables. Clearly, it can only have one name. The name is a property of the function, not of the variable.
      – usr
      Nov 13 at 19:27




      Another way to see this is that the same function could be referred to by multiple variables. Clearly, it can only have one name. The name is a property of the function, not of the variable.
      – usr
      Nov 13 at 19:27












      up vote
      14
      down vote













      Importing an object just binds a new variable, and all that adding as newname does is let you pick an alternative name to use for the variable in the current namespace.



      The __name__ attribute on an object says nothing about the name it is currently bound to, you can have any number of variables as well as containers such as lists or dictionaries pointing to the same object, after all:



      def foo(): pass

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


      The above created 4 additional references to the function object; you can't have foo.__name__ reflect all of those, and the references in list_of_functions and dictionary_of_functions do not (directly) have names.



      Since import foo, import bar as foo, from module import foo and from module import bar as foo all just set the name foo in the current module, they are treated the exact same way as other assignments. You could import the function more than once, under different names, too.



      Instead, the __name__ value of a function is set to name it was defined with in the def <name>(...): statement. It is a debugging aid, at most. It is used in tracebacks, for example, to make it easier to identify lines of code shown in the traceback. You'd only set the __name__ to something else if that would help identify the location better. (Note: in Python 3, there is also the __qualname_ attribute, which is used instead of __name__ as it includes more information on where the function is defined when nested or defined on a class).






      share|improve this answer



























        up vote
        14
        down vote













        Importing an object just binds a new variable, and all that adding as newname does is let you pick an alternative name to use for the variable in the current namespace.



        The __name__ attribute on an object says nothing about the name it is currently bound to, you can have any number of variables as well as containers such as lists or dictionaries pointing to the same object, after all:



        def foo(): pass

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


        The above created 4 additional references to the function object; you can't have foo.__name__ reflect all of those, and the references in list_of_functions and dictionary_of_functions do not (directly) have names.



        Since import foo, import bar as foo, from module import foo and from module import bar as foo all just set the name foo in the current module, they are treated the exact same way as other assignments. You could import the function more than once, under different names, too.



        Instead, the __name__ value of a function is set to name it was defined with in the def <name>(...): statement. It is a debugging aid, at most. It is used in tracebacks, for example, to make it easier to identify lines of code shown in the traceback. You'd only set the __name__ to something else if that would help identify the location better. (Note: in Python 3, there is also the __qualname_ attribute, which is used instead of __name__ as it includes more information on where the function is defined when nested or defined on a class).






        share|improve this answer

























          up vote
          14
          down vote










          up vote
          14
          down vote









          Importing an object just binds a new variable, and all that adding as newname does is let you pick an alternative name to use for the variable in the current namespace.



          The __name__ attribute on an object says nothing about the name it is currently bound to, you can have any number of variables as well as containers such as lists or dictionaries pointing to the same object, after all:



          def foo(): pass

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


          The above created 4 additional references to the function object; you can't have foo.__name__ reflect all of those, and the references in list_of_functions and dictionary_of_functions do not (directly) have names.



          Since import foo, import bar as foo, from module import foo and from module import bar as foo all just set the name foo in the current module, they are treated the exact same way as other assignments. You could import the function more than once, under different names, too.



          Instead, the __name__ value of a function is set to name it was defined with in the def <name>(...): statement. It is a debugging aid, at most. It is used in tracebacks, for example, to make it easier to identify lines of code shown in the traceback. You'd only set the __name__ to something else if that would help identify the location better. (Note: in Python 3, there is also the __qualname_ attribute, which is used instead of __name__ as it includes more information on where the function is defined when nested or defined on a class).






          share|improve this answer














          Importing an object just binds a new variable, and all that adding as newname does is let you pick an alternative name to use for the variable in the current namespace.



          The __name__ attribute on an object says nothing about the name it is currently bound to, you can have any number of variables as well as containers such as lists or dictionaries pointing to the same object, after all:



          def foo(): pass

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


          The above created 4 additional references to the function object; you can't have foo.__name__ reflect all of those, and the references in list_of_functions and dictionary_of_functions do not (directly) have names.



          Since import foo, import bar as foo, from module import foo and from module import bar as foo all just set the name foo in the current module, they are treated the exact same way as other assignments. You could import the function more than once, under different names, too.



          Instead, the __name__ value of a function is set to name it was defined with in the def <name>(...): statement. It is a debugging aid, at most. It is used in tracebacks, for example, to make it easier to identify lines of code shown in the traceback. You'd only set the __name__ to something else if that would help identify the location better. (Note: in Python 3, there is also the __qualname_ attribute, which is used instead of __name__ as it includes more information on where the function is defined when nested or defined on a class).







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 13 at 12:15

























          answered Nov 13 at 12:03









          Martijn Pieters

          689k12723782226




          689k12723782226






















              up vote
              0
              down vote













              The as is syntactical sugar in the file/session of the import, while the __name__ attribute is part of the function object.






              share|improve this answer

























                up vote
                0
                down vote













                The as is syntactical sugar in the file/session of the import, while the __name__ attribute is part of the function object.






                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  The as is syntactical sugar in the file/session of the import, while the __name__ attribute is part of the function object.






                  share|improve this answer












                  The as is syntactical sugar in the file/session of the import, while the __name__ attribute is part of the function object.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 13 at 12:01









                  halloleo

                  2,30942257




                  2,30942257






























                       

                      draft saved


                      draft discarded



















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53280530%2fwhy-does-an-imported-function-as-another-name-keep-its-original-name%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Сан-Квентин

                      Алькесар

                      Josef Freinademetz