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










18















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 '18 at 14:48















18















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 '18 at 14:48













18












18








18


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 '18 at 11:56









BasjBasj

6,00530105231




6,00530105231







  • 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 '18 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 '18 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 '18 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 '18 at 14:48












3 Answers
3






active

oldest

votes


















35














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



>>> 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 '18 at 11:59






  • 4





    @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 '18 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 '18 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 '18 at 12:05







  • 2





    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 '18 at 19:27


















16














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
































    0














    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',
      autoActivateHeartbeat: false,
      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









      35














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



      >>> 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 '18 at 11:59






      • 4





        @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 '18 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 '18 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 '18 at 12:05







      • 2





        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 '18 at 19:27















      35














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



      >>> 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 '18 at 11:59






      • 4





        @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 '18 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 '18 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 '18 at 12:05







      • 2





        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 '18 at 19:27













      35












      35








      35







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



      >>> 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__ attribute when you assign another name to the function.



      >>> 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 21 '18 at 10:05

























      answered Nov 13 '18 at 11:57









      timgebtimgeb

      50.8k116493




      50.8k116493












      • @Basj there is no such attribute. Names (bar) refer to values (the function) unidirectionally.

        – timgeb
        Nov 13 '18 at 11:59






      • 4





        @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 '18 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 '18 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 '18 at 12:05







      • 2





        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 '18 at 19:27

















      • @Basj there is no such attribute. Names (bar) refer to values (the function) unidirectionally.

        – timgeb
        Nov 13 '18 at 11:59






      • 4





        @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 '18 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 '18 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 '18 at 12:05







      • 2





        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 '18 at 19:27
















      @Basj there is no such attribute. Names (bar) refer to values (the function) unidirectionally.

      – timgeb
      Nov 13 '18 at 11:59





      @Basj there is no such attribute. Names (bar) refer to values (the function) unidirectionally.

      – timgeb
      Nov 13 '18 at 11:59




      4




      4





      @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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 at 12:05





      2




      2





      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 '18 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 '18 at 19:27













      16














      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





























        16














        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



























          16












          16








          16







          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 '18 at 12:15

























          answered Nov 13 '18 at 12:03









          Martijn PietersMartijn Pieters

          711k13724812301




          711k13724812301





















              0














              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



























                0














                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

























                  0












                  0








                  0







                  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 '18 at 12:01









                  halloleohalloleo

                  2,41252258




                  2,41252258



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      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

                      Use pre created SQLite database for Android project in kotlin

                      Darth Vader #20

                      Ondo