Factsheet
How to use the -c flag in python - Stack Overflow
Understanding what CPython actually IS has greatly enhanced my understanding of Python.
How are Python and C related? I've read that Python is 'made from C'. Does that mean that Python is just an abstraction of lots of large C functions?
How do you call Python code from C code? - Stack Overflow
Videos
Just pass regular Python code as the argument to the flag:
python -c 'print 1
print 2'
Import modules works, and blank lines are OK, too:
python -c '
import pprint
pprint.pprint(1)
'
When using this feature, just be mindful of shell quoting (and indentation), and keep in mind that if you're using this outside of a few shell scripts, you might be doing it wrong.
Easiest example
python -c "print 'example'"
It is useful whenever your program has a single line of code, for example, list comprehensions, etc.
Another example can be
python -c "a='example';print a"
As you can see, multiple statements are separated by ;
First off, its perfectly understandable to not really care about language theory as a beginner. This stuff is not necessary to learn to code.
However, after recently doing some deep dives on what CPython really is and how it works, I have found the knowledge to be extremely enlightening. And it has really opened my eyes as to how Python is used, and why its used in the places it is.
For those who are unaware, allow me to share what I've learned.
So the key piece of information is that CPython is, at its core, a program written in C. Its purpose is to take Python code as input, then convert that Python into its own native instructions (written in C), and then execute them. And perhaps most importantly, it does this in a line-by-line manner. That just means it doesn't try to error check the entire program before running it. Potential errors just happen as it goes through each line of code, one by one.
However its also important to understand that Python is actually still semi-compiled into "bytecode", which is an intermediate stage between Python and full machine code. CPython converts your python scripts into bytecode files first, so what it actually runs is the bytecode files.
Now where it gets super interesting is that CPython is not the only "implementation" of Python (implementation means some kind of program, or system, that takes Python code as input and does something with it). More on that later.
On the subject of bytecode, it naturally leads to some other interesting questions, such as "Can I share the bytecode files?", to which the answer is no. That's one of the key aspects of CPython. The bytecode is "not platform agnostic". (I'm really sorry if that's not the correct term, I just learned all this stuff recently). That means the bytecode itself is compiled for your specific environment (the python version and dependencies). The reason for this is that its part of Python's design philosophy to be constantly improving the bytecode.
Once you understand that you can then comprehend what other implementations of Python do. PyPy for instance aims to make a Python running environment that works more like Java, where it performs "just-in-time" compilation to turn the bytecode into native machine code at runtime, and that's why it can make certain things run faster. Then you have the gamut of other ways Python can be used, such as:
-
Cython - aims to translate Python into C, which can then be compiled
-
Nuitka - aims to translate Python into C++, which is more versatile and less restrictive
-
Jython - this semi-compiles Python into Java bytecode that can be run in a Java virtual machine/runtime
-
IronPython - semi-compiles Python into C# bytecode, for running in .NET runtime
-
PyPy - A custom JIT-compiler that works in a manner philosophically similar to Java
-
MicroPython - a special version of python that's made for embedded systems and 'almost' bare-metal programming
Oh and then there's also the fact that if you want to use Python for scripting while working in other languages, its important to understand the difference between calling CPython directly, or using "embedded" CPython. For instance some game coders might opt to just call CPython as an external program. However some might opt to just build CPython directly into the game itself so that it does not need to. Different methods might be applicable to different uses.
Anyway all of this shit has been very entertaining for me so hopefully someone out there finds this interesting.
Any clarification is welcome!
I recommend the approaches detailed here. It starts by explaining how to execute strings of Python code, then from there details how to set up a Python environment to interact with your C program, call Python functions from your C code, manipulate Python objects from your C code, etc.
EDIT: If you really want to go the route of IPC, then you'll want to use the struct module or better yet, protlib. Most communication between a Python and C process revolves around passing structs back and forth, either over a socket or through shared memory.
I recommend creating a Command struct with fields and codes to represent commands and their arguments. I can't give much more specific advice without knowing more about what you want to accomplish, but in general I recommend the protlib library, since it's what I use to communicate between C and Python programs (disclaimer: I am the author of protlib).
Have you considered just wrapping your python application in a shell script and invoking it from within your C application?
Not the most elegant solution, but it is very simple.
I want to invoke those C function or executables in python. Is that possible.
Yes, you can write C code that can be imported into Python as a module. Python calls these extension modules. You can invoke it from Python directly, an example from the documentation:
Python Code
import example
result = example.do_something()
C Code
static PyObject * example(PyObject *self)
{
// do something
return Py_BuildValue("i", result);
}
If I want the C code to be a library, which means I use it with #include and linkage of the *.o likely in python, how to do it or is that possible.
You build it as a shared library *.dll or *.so You can also investigate using distutils to distribute your module.
If I write the C code into executable, which means it becomes a command, can I invoke it in python directly?
If you write a *.exe then you are doing the opposite (invoking Python from C). The method you choose (exe vs shared library) depends on if you want a "C program with some Python" or a "Python program with some C".
Also, I heard that python code can be compiled, does that mean we can execute the code without the source file? Are the output files binary files? Does it improve performance?
Python reads *.py files and compiles to *.pyc bytecode files when you run it. The bytecode is then run in the Python virtual machine. This means "executing the same file is faster the second time as recompilation from source to bytecode can be avoided." (from the Python glossary) So if you haven't edited your *.py files, it will run the *.pyc. You can distribute *.pyc files without *.py files, however they are not encrypted and can be reverse-engineered.
You don't necessary need to extend Python (which is not trivial, btw), but can use foreign function interface such as ctypes.
From everything I've seen, it's a combination of practical and historical reasons. The (mostly) historical reason is that CPython 1.0 was released in 1989. At that time, C was just recently standardized. C++ was almost unknown and decidedly non-portable, because almost nobody had a C++ compiler.
Although C++ is much more widespread and easily available today, it would still take a fair amount of work to rewrite CPython into the subset of C that's compatible with C++. By itself, that work would provide little or no real benefit.
It's a bit like Joel's blog post about starting over and doing a complete rewrite being the worst mistake a software company can make. I'd counter that by pointing to Microsoft's conversion from the Windows 3.0 core to the Windows NT core, and Apple's conversion from MacOS 9 to Mac OS/X. Neither one killed the company -- but both were definitely large, expensive, long-term projects. Both also point to something that's crucial to success: maintaining both code bases for long enough that (most) users can switch to the new code base at their leisure, based on (at least perceived) benefits.
For a development team the size of Python's, however, that kind of change is much more difficult. Even the change from Python 2 to 3 has taken quite a bit of work, and required a similar overlap. At least in that case, however, there are direct benefits to the changes, which rewriting into C++ (by itself) wouldn't (at least immediately) provide.
Linus Torvalds's rant against C++ was brought up, so I'll mention that as well. Nothing I've seen from Guido indicates that he has that sort of strong, negative feelings toward C++. About the worst I've seen him say is that teaching C++ is often a disaster -- but he immediately went on to say that this is largely because the teachers didn't/don't know C++.
I also think that while it's possible to convert a lot of C code to C++ with relative ease, that getting much real advantage from C++ requires not only quite a bit more rewriting than that, but also requires substantial re-education of most developers involved. Most well-written C++ is substantially different from well-written C to do the same things. It's not just a matter of changing malloc to new and printf to cout, by any stretch of the imagination.
I think the reason why it was originally written in ANSI C89 is quite simply because back then, C++ was just not a workable choice what with incompatibilities between different compilers and such. I mean, it took until, what was it, 2005, to come up with an ABI specification that would allow code compiled with one compiler to call code compiled with a different compiler?
The more interesting question is why it is still written in C89.
And there is a surprising answer: because people actually use Python on platforms for which no C++ and no C99 compiler exists! When the Forth-inspired threaded-code interpreter optimizations were merged, there was a huge discussion about it, because the code (necessarily) used computed goto which is not a part of C89. There were apparently real fears that this feature might not be available on some of the platforms that Python is currently used on.
The same thing happened with Unladen Swallow, wich uses LLVM, which is written in C++. It was made very clear that a requirement for merging Unladen Swallow into CPython would be that you can compile it without the JIT compiler, since there are platforms people run Python on, for which no C++ compiler exists.
Of course, nowadays, CPython is no longer the only Python implementation. There is PyPy, which is written in RPython (a statically typed subset of Python), Jython in Java, IronPython in C#, Pynie in NQP and PIR and so on.