9

I've been using Python for a good period of time. I have never found out how built-in functions work. In different words, how are they included without having any module imported to use them? What if I want to add to them (locally)?

This may seem naive. But, I haven't really found any answer that explains comprehensively how do we have built-in functions, global variables, etc., available to us when developing a script.

In a nutshell, where do we include the builtins module?

I have encountered this question. But it gives a partial answer to my question.

ndrwnaguib
  • 5,623
  • 3
  • 28
  • 51
  • 1
    They are built directly into the interpreter – UnholySheep Jan 13 '19 at 22:04
  • 1
    You mean, they're compiled into the interpreter executable? – ndrwnaguib Jan 13 '19 at 22:05
  • 2
    Yes, they are part of the interpreter itself, not separated out into their own modules – UnholySheep Jan 13 '19 at 22:06
  • 1
    You don't want to add to them (locally), except by defining non-built in functions. The last thing you want for readable code is functions that aren't in the standard globals but randomly appear anyway. – jonrsharpe Jan 13 '19 at 22:07
  • 3
    @UnholySheep they are in the `builtins` module though. – gilch Jan 13 '19 at 22:08
  • 2
    @gilch: And there is [some (limited) precedent for dynamically adding stuff to the built-in namespace](https://docs.python.org/3/library/constants.html#constants-added-by-the-site-module). – ShadowRanger Jan 13 '19 at 22:24
  • 1
    @ShadowRanger besides the standard library, I know that ipython and xonsh mess with builtins. – gilch Jan 13 '19 at 22:28
  • For example the `gettext` package is able to "install" new functions (e.g. `_()`) into that builtins namespace. See "class based API" in the packages docu. – buhtz Aug 17 '23 at 07:12

1 Answers1

7

The not-implementation-details part of the answer is that the builtins module, or __builtin__ in Python 2, provides access to the built-ins namespace. If you want to modify the built-ins (you usually shouldn't), setting attributes on builtins is how you'd go about it.

The implementation details part of the answer is that Python keeps track of built-ins in multiple ways. For example, each frame object keeps track of the built-in namespace it's using, which may be different from other frames' built-in namespaces. You can access this through a frame's f_builtins attribute. When a LOAD_GLOBAL instruction fails to find a name in the frame's globals, it looks in the frame's builtins. There's also a __builtins__ global variable in most global namespaces, but it's not directly used for built-in variable lookup; instead, it's used to initialize f_builtins in certain situations during frame object creation. There's also a builtins reference in the global PyInterpreterState, which is used as default builtins if there's no current frame object.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • 1
    The docs for the `exec` function also mention that you can customize which `__builtins__` it uses by specifying it in the globals dict argument. – gilch Jan 13 '19 at 22:26
  • 1
    @gilch: That's not *quite* what they say, but under usual circumstances, setting `__builtins__` in the global dict passed to `exec` will control the builtins used for the executed code, through the usual initialize-`f_builtins`-from-`__builtins__` handling. There is a weird exception [if you try to set `__builtins__` in the current globals and then pass those globals to `exec`](https://ideone.com/yl9fvN), since that hits the other code path for initializing `f_builtins`. – user2357112 Jan 13 '19 at 22:40