23

I am new to python programming. How can I add new built-in functions and keywords to python interpreter using C or C++?

martineau
  • 119,623
  • 25
  • 170
  • 301
Rubia
  • 445
  • 2
  • 6
  • 17

5 Answers5

32

In short, it is technically possible to add things to Python's builtins, but it is almost never necessary (and generally considered a very bad idea).

In longer, it's obviously possible to modify Python's source and add new builtins, keywords, etc… But the process for doing that is a bit out of the scope of the question as it stands.

If you'd like more detail on how to modify the Python source, how to write C functions which can be called from Python, or something else, please edit the question to make it more specific.

If you are new to Python programming and you feel like you should be modifying the core language in your day-to-day work, that's probably an indicator you should simply be learning more about it. Python is used, unmodified, for a huge number of different problem domains (for example, numpy is an extension which facilitates scientific computing and Blender uses it for 3D animation), so it's likely that the language can handle your problem domain too.

†: you can modify the __builtin__ module to “add new builtins”… But this is almost certainly a bad idea: any code which depends on it will be very difficult (and confusing) to use anywhere outside the context of its original application. Consider, for example, if you add a greater_than_zero “builtin”, then use it somewhere else:

$ cat foo.py
import __builtin__
__builtin__.greater_than_zero = lambda x: x > 0

def foo(x):
    if greater_than_zero(x):
        return "greater"
    return "smaller"

Anyone who tries to read that code will be confused because they won't know where greater_than_zero is defined, and anyone who tries to use that code from an application which hasn't snuck greater_than_zero into __builtin__ won't be able to use it.

A better method is to use Python's existing import statement: http://docs.python.org/tutorial/modules.html

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
David Wolever
  • 148,955
  • 89
  • 346
  • 502
  • 4
    Actually, you can. The `__builtins__` module is writable. – Keith Aug 06 '11 at 06:06
  • @Keith: this is true — it *is* possible to modify `__builtins__`. However, A) it goes without saying that this is a terrible, terrible idea, and B) I feel like the question is asking how to extend the core language, so I didn't think it was worth bringing that up in the answer. – David Wolever Aug 06 '11 at 06:12
  • @eryksun Where do you think those builtin functions go? They are the same. You can write a site wrapper that imports your C extension and places it's symbols in `__builtins__`, if you really wanted to. – Keith Aug 06 '11 at 06:24
  • 1
    @eryksun I have. But when someone says "builtin" in the Python context that has a special meaning. At least to me. It basically means its a global object. The OP specifically wants to muck with the language, even adding new keywords. That's not in the builtin, but much of the language is actually those builtin functions. – Keith Aug 06 '11 at 09:51
  • 2
    @david. Ok, but I'm curious what your argument would be against not doing it. What is wrong with it? Something better than "trust me". ;-) – Keith Aug 06 '11 at 09:54
  • 4
    Here is a legitimate use case: my python app has a flag to launch in debug mode. It adds lots of utility functions to `__builtins__` so that they are available in every context while debugging and calls pdb.set_trace(). Nothing wrong with that since it for my own consumption only right? I get annoyed with the way SO answers can get really preachy, thanks Keith for contributing to actually make this site useful. The accepted answer is misleading and the preview in Google leads you to believe it is a very difficult thing to do. This should be fixed. – spam_eggs Oct 23 '12 at 22:24
  • @spam_eggs trust me, I dislike preachy answers as much as you. However, I believe that my current answer is "best": the "in short" qualification makes it clear that, while it's possible, adding things to `__builtins__` isn't something you should normally be doing (ex, in the same way monkeypatching is *possible* but not *encouraged*), but the footnote explains how to do it if you've got a Good Reason. Please edit the answer if you've got a better wording, though. – David Wolever Oct 23 '12 at 22:33
  • @david Given this page is currently the first Google hit for the query "add python builtin" I would reword the answer as follows: "You can add these to `__builtins__` however be warned this is not recommended practice in most cases, for the following reasons etc." or something to the effect. Guess I mainly wanted to show valid use cases exist. – spam_eggs Oct 23 '12 at 23:17
  • 2
    David, are you sure it shouldn't be `__builtin__` instead of `__builtins__`? See [Python: What's the difference between __builtin__ and __builtins__?](http://stackoverflow.com/q/11181519/95735) – Piotr Dobrogost May 02 '13 at 07:45
  • One _valid_ example for monkey-patching a builtin is [having round call a class' __round__ if provided](http://stackoverflow.com/q/16058529/321973) – Tobias Kienzler Aug 14 '13 at 08:04
  • I found this snippet reduced a lot of annoyance for quick and dirty debugging (not worthy of a permanent `logger.debug` call) in my development environment: in a .gitignored `local_config.py` file have `from pprint import pprint; __builtins__['pprint'] = pprint` ... I don't really see anything wrong with that as no commit will ever use it nor will it ever hit prod. – mVChr Apr 15 '15 at 23:50
  • @spam_eggs if you are modifying `__builtins__` for debugging, you could just as easily pass in a modified `globals()`, or add some `import ...` beforehand? – Cireo Jun 13 '19 at 00:55
6

for python 3.6 onward use import builtins.


# example 1

import builtins

def f():
    print('f is called')

builtins.g = f

g() # output = f is called

####################################
# example 2

import builtins

k = print

def f(s):
    k('new print called : ' + s)

builtins.print = f

print('abc') # output = new print is called abc


martineau
  • 119,623
  • 25
  • 170
  • 301
1

While David Wolever's answer is perfect, it should be noted again that the asker is new to Python. Basically all he wants is a global function, which can be done in two different ways...

  1. Define a function in your module and use it.
  2. Define a function in a different module and import it using the "from module import *" statement.

I think the asker's solution is the 2nd option and anyone new to Python having this question should look in to the same.

For an advance user, I would agree with Wolever's suggestion that it is a bad idea to insert a new function in to the builtin module. However, may be the user is looking for a way to avoid importing an always-used module in every script in the project. And that is a valid use case. Of course the code will not make sense to people who aren't part of the project but that shouldn't be a concern. Anyways, such users should look in to the PYTHONSTARTUP environment variable. I would suggest looking it up in the Index of the Python documentation and look at all links that talks about this environment variable and see which page serves your purpose. However, this solution works for interactive mode only and does not work for sub-main script.

For an all around solution look in to this function that I have implemented: https://drive.google.com/file/d/19lpWd_h9ipiZgycjpZW01E34hbIWEbpa/view

Yet another way is extending or embedding Python and it is a relatively complex topic. It is best to read the Python documentation on the same. For basic users, all I would say is that...

  • Extending means adding new builtin modules to the Python interpreter.
  • Embedding means inserting Python interpreter into your application.

And advanced users already know what they are doing!

RcnRcf
  • 356
  • 1
  • 8
0

You can use builtins module.

Example 1:

import builtins

def write(x):
    print(x)

builtins.write = write

write("hello")

# output:
# Hello

Example 2:

import builtins

def hello(*name):
    print(f"Hello, {' '.join(name)}!")

builtins.hello = hello

hello("Clark", "Kent")

# output:
# Hello, Clark Kent!
0

Without importing builtins module:

# module A

def func(): ...

__builtins__.func = func
# module B

__builtins__['func']()  # or just func()
Saber Hayati
  • 688
  • 12
  • 14