Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Python deals with objects that come from "elsewhere"

This may be a stupid question, but I don't get in Python how we can use object that we did not some define or imported.

Consider the following example, using Python's datetime module:

from datetime import date

date1 = date(2019,1,1)
date2 = date(2019,1,5)

type(date2-date1) #<class 'datetime.timedelta'>
type(date2)       #<class 'datetime.date'>

Then date2-date1 is of timedelta class, even though we haven't imported this.

(I could probably also cook up other examples, where we obtain objects, even though we haven't defined them.)

How can this be?

Should I think about these new objects that pop up simply as pieces in memory that are being returned by other functions, that, even though we haven't defined them, contain "in themselves" enough information so that the Python interpreter can meaningfully apply the type() and other functions to them?

like image 691
l7ll7 Avatar asked Mar 04 '23 13:03

l7ll7


1 Answers

You are incorrectly assuming that import limits what is loaded into memory. import limits what names are bound in your module globals.

The whole module is still loaded, as are dependencies of that module. Just because your namespace doesn't bind a reference to the datetime.timedelta object doesn't mean it is not available to the datetime module.

See the import statement documentation:

The from form uses a slightly more complex process:

  1. find the module specified in the from clause, loading and initializing it if necessary;
  2. for each of the identifiers specified in the import clauses:
    1. check if the imported module has an attribute by that name
    2. if not, attempt to import a submodule with that name and then check the imported module again for that attribute
    3. if the attribute is not found, ImportError is raised.
    4. otherwise, a reference to that value is stored in the local namespace, using the name in the as clause if it is present, otherwise using the attribute name

So loading and initialising of modules is a separate step, executed once per module. The second step binds names in your namespace.

from datetime import date makes sure the datetime module is loaded, then finds datetime.date and adds date = datetime.date to your namespace.

If you want to see what modules are loaded, check out the sys.modules mapping. That's the location that the import statement machinery checks to see if a given module has been loaded yet.

like image 63
Martijn Pieters Avatar answered Mar 11 '23 14:03

Martijn Pieters