1

I am new to Python.

In Python when we say print("hello"), is an object with "hello" created and stored on heap and then printed or it's just print without an object?

3
  • Well, in CPython, 'hello' the str object is cached by the compiler, but that is an optimization Commented Dec 6, 2021 at 20:58
  • But the way you think about it is correct Commented Dec 6, 2021 at 20:59
  • 1
    And really, just stop thinking about the heap in Python. Python is a memory managed language, the way this works is an implementation detail. in CPython, all objects (i.e. everything) is allocated on a privately managed heap. Commented Dec 6, 2021 at 21:02

2 Answers 2

4

You can try to disassemble it and you'll see. Python is an interpreted language with its interpreter being a virtual machine (think assembly compiled to machine instructions, but a bit abstracted from the hardware layer to the software layer).

For disassembling Python provides an easy dis.dis() function.

import dis def hello(): print("hello") dis.dis(hello) 

It creates the value (I'd guess while parsing, but don't quote me on that. I'd need to check the CPython's code for that) as a constant and then loads it back in the VM when using the print function's C implementation.

Now where it's created is dependent on the underlying Python language interpreter, in this case CPython (and PyPy is another one). For CPython it'd be this:

Memory management in Python involves a private heap containing all Python objects and data structures. (ref)

Not guaranteed for Python as an independent language, but most likely yes, it'd be on heap due to "hello" string not being encapsulated in a simple data storage (int, char, etc, the low level types), but in a complex C structure. Or better said a Python object (PyObject), which is in general thrown on heap with Python's malloc or so called PyMalloc or other malloc-like implementation the interpreter chooses to use either by compile-time options or library detection on the runtime.

 4 0 LOAD_GLOBAL 0 (print) 2 LOAD_CONST 1 ('hello') 4 CALL_FUNCTION 1 6 POP_TOP 8 LOAD_CONST 0 (None) 10 RETURN_VALUE 

However, as noted in the comments, and as with every modern compiler (so even Python's) the code can be optimized, therefore it can be even thrown into a raw C data storage (e.g. *char[] or similar) and then only referenced via the Python's object or whatever the optimization's author wishes. To get better details how it's handled you'd need to check the compiler's code and a bit after the compilation step when the optimizations might be handled as well.

A bit simpler disassembling with just the code you have. dis.dis() accesses the code block in the hello() function, so the result is the same, just the line on the left isn't 4 but a 1

$ cat main.py;echo "---";python -m dis main.py print("hello") --- 1 0 LOAD_NAME 0 (print) 2 LOAD_CONST 0 ('hello') 4 CALL_FUNCTION 1 6 POP_TOP 8 LOAD_CONST 1 (None) 10 RETURN_VALUE 

Related:

Sign up to request clarification or add additional context in comments.

3 Comments

technically, the bytecode is an implementation detail
Agreed. It might not even be exposed and just shoveled into the VM or executed JIT.
And yes, that object is created during compilation. It is stored in the code object that is created during this phase, and is actually accessible through hello.__code__.co_consts if you want to know some cool instrospection capabilities
1

I believe it creates a str object which has the method str(), which print() calls, then it gets garbage collected afterwards, but I may be wrong

2 Comments

conceptually this is what happens, although in CPython this is optimized to re-use a pre-cached str object, and it will work that way for other immutable literal expressions
ok thanks for the clarification

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.