Wo verstecken sich die Funktionen in den Modulen?
-
- User
- Beiträge: 8
- Registriert: Dienstag 4. Februar 2014, 21:40
Ich programmiere seit kurzer Zeit in Python und versuche mir hin und wieder die Implementation von Funktionen in den Modulen anzuschauen. In vielen Fällen kann ich die entsprechenden Funktionen aber nicht ausfindig machen. Um beispielsweise die Funktion gethostbyaddr() in einem Programm zu verwenden, muss ich das Modul socket einbinden. Also denk ich mir, das irgendwo in der Datei /usr/lib/python2.7/socket.py die Funktion gethostbyaddr() definiert ist. Und in dieser Datei steht ja auch: "This module provides socket operations and some related functions. [...] gethostbyaddr()". Aber eine Definition dieser Funktion ist dort nicht zu finden. Wo steckt die Dinger also?
Die steckt im _socket-Modul. Steht auch in den ersten beiden Zeilen:
Code: Alles auswählen
# Wrapper module for _socket, providing some additional facilities
# implemented in Python.
Das Leben ist wie ein Tennisball.
- pillmuncher
- User
- Beiträge: 1484
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Und hier ist der Source Code dazu: http://hg.python.org/cpython/file/e0bca ... le.c#l4418
In specifications, Murphy's Law supersedes Ohm's.
-
- User
- Beiträge: 8
- Registriert: Dienstag 4. Februar 2014, 21:40
ok, danke. die nächste frage lautet natürlich: wo finde ich das _socket modul? als datei auf meinem rechner jedenfalls nicht. geh ich recht davon aus, dass das, was socket.py als _socket importiert, irgendwo in vorkompilierten biliotheken steckt?
@Diego Brei: Folge dem Link den Pillmuncher gepostet hat. Das Modul ist in C impementiert und nicht in Python.
-
- User
- Beiträge: 8
- Registriert: Dienstag 4. Februar 2014, 21:40
@Blckjack: Ja, das habe ich schon verstanden. Aber der Python-Interpreter wird ja auch nicht den Code aus dem geposteten Link auslesen. Ich will halt wissen, was der Interpeter macht, wenn ich eine Funktion benutze. Bis jetzt waren wir so weit, dass ein Modul namens _socket eingebunden wird, in dem der Code steht? Wobei ich nicht weiß, wo dieses _socket-Modul auf meinem Rechner sein soll.
- pillmuncher
- User
- Beiträge: 1484
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Ich tippe mal auf <python dir>\libs\_socket.lib unter Windows. Oder <cygwin dir>/lib/python2.7/lib-dynload/_socket.dll unter Cygwin. Linux/Unix hab ich gerade keines laufen, deswegen kann ich nicht nachschauen.
Zuletzt geändert von pillmuncher am Mittwoch 5. Februar 2014, 00:53, insgesamt 1-mal geändert.
In specifications, Murphy's Law supersedes Ohm's.
@Diego Brei: Also bei mir ist es direkt mit in den Interpreter einkompiliert:
Wenn Du es einfach importierst und den Wert des Moduls ausgibst, dann siehst Du ob es „eingebaut” ist, oder ob und wenn dann wo die Datei liegt in der der Code steht.
Code: Alles auswählen
In [24]: import _socket
In [25]: _socket
Out[25]: <module '_socket' (built-in)>
In [26]: import sys
In [27]: sys.builtin_module_names
Out[27]:
('__builtin__',
'__main__',
'_ast',
'_bisect',
'_codecs',
'_collections',
'_functools',
'_hashlib',
'_locale',
'_random',
'_socket',
'_sre',
'_ssl',
'_struct',
'_symtable',
'_warnings',
'_weakref',
'array',
'binascii',
'cPickle',
'cStringIO',
'cmath',
'errno',
'exceptions',
'fcntl',
'gc',
'grp',
'imp',
'itertools',
'marshal',
'math',
'operator',
'posix',
'pwd',
'select',
'signal',
'spwd',
'strop',
'sys',
'syslog',
'thread',
'time',
'unicodedata',
'xxsubtype',
'zipimport',
'zlib')
-
- User
- Beiträge: 8
- Registriert: Dienstag 4. Februar 2014, 21:40
ok, das scheint bei mir auch der fall zu sein.
einige module sind also direkt in den interpreter eingebaut und der quellcode muss dabei gar nicht auf dem system hinterlegt sein.
einige module sind also direkt in den interpreter eingebaut und der quellcode muss dabei gar nicht auf dem system hinterlegt sein.
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Der Quellcode muss so oder so nicht hinterlegt werden, da weder fuer Python-Code noch fuer C-Code (im Fall von `_socket` und anderen CPython Interna) der Quellcode ausgefuehrt wird.
Was vorliegen muss ist der Bytecode (Python-Code) bzw der Binaercode (C-Code).
Selbst wenn `_socket` nicht statisch in das Python Binary gelinkt wuerde, sondern zB als ".pyd" vorliegen und eingebunden wuerde, haettest du keinen (angenehm) lesbaren Code.
Was vorliegen muss ist der Bytecode (Python-Code) bzw der Binaercode (C-Code).
Selbst wenn `_socket` nicht statisch in das Python Binary gelinkt wuerde, sondern zB als ".pyd" vorliegen und eingebunden wuerde, haettest du keinen (angenehm) lesbaren Code.
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
@Diego Brei: Bei vielen Sprachen (selbst wenn sie als "Skriptsprache" gelten) ist es so, dass der Quelltext zunächst in eine andere und äußerst primitive Sprache überführt werden muss, bevor man ihn ausführen kann. Diese Überführung geschieht in einigen Sprachen explizit, indem der Kompilierungsvorgang mittels Befehl in Gang gesetzt werden muss. In Python geschieht es implizit, indem nach Aufruf des ``python``-Befehls geschaut wird, ob für die aktuelle Datei bereits eine Bytecode-Version vorliegt (wird anhand von Änderungsdatum und Dateiname ermittelt). Wenn schon aktueller Bytecode (also die "Primitiv-Version") vorhanden ist, dann wird dieser direkt ausgeführt. Andernfalls wird vorab kompiliert und danach der Bytecode ausgeführt. Der ursprüngliche Quelltext ist hauptsächlich dafür gedacht, dass ein Mensch das Programm einigermaßen leicht verstehen kann. Das ist aber meistens nicht das, was der Computer beim Ausführen später zu "sehen" bekommt.
-
- User
- Beiträge: 8
- Registriert: Dienstag 4. Februar 2014, 21:40
Mir ist nie so recht klar gewesen, was es mit Bytecode auf sich hat. Meistens kann man lesen, dass der Compiler/Interpreter den Quellcode zunächst in ein Zwischenstadium übersetzt bevor er daraus für die CPU ausführbaren Code generiert. Das kenn ich von C (.o), von Java (.class) und nun von Python (.pyc). Was soll der Sinn dieser Zwischenstufe sein? Etwa, dass der Bytecode Systemunabhängig ist? Dann könnte man ja den Machinencode auch gleich aus den Quellen übersetzen. Oder bring ich was durcheinander?
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
.pyc und .class sind Bytecode, .o ist allerdings Binaer-/Maschinencode.
Und nein, Bytecode ist nicht systemunabhaengig, im Allgemeinen sogar das Gegenteil: Systemspezifisch (fuer die Version des jeweiligen Bytecode-Interpreters).
Der Sinn ist ganz einfach der, dass Bytecode einfacher auszufuehren ist, da dabei das urspruengliche Programm in relativ wenige unterschiedliche Befehle heruntergebrochen (und dabei laenger im Allgemeinen laenger) wird.
Mit dem Modul `dis` kann man sich Bytecode "lesbar" machen:
Und nein, Bytecode ist nicht systemunabhaengig, im Allgemeinen sogar das Gegenteil: Systemspezifisch (fuer die Version des jeweiligen Bytecode-Interpreters).
Der Sinn ist ganz einfach der, dass Bytecode einfacher auszufuehren ist, da dabei das urspruengliche Programm in relativ wenige unterschiedliche Befehle heruntergebrochen (und dabei laenger im Allgemeinen laenger) wird.
Mit dem Modul `dis` kann man sich Bytecode "lesbar" machen:
Code: Alles auswählen
In [11]: import dis
In [12]: def a():
print "Hello World"
....:
In [13]: dis.dis(a)
2 0 LOAD_CONST 1 ('Hello World')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
@Diego Brei: snafu hat die Begründung eigentlich schon genannt: Quelltext ist für den Menschen zum schreiben, lesen, und verstehen optimiert (zumindest bei brauchbaren Programmiersprachen ) aber in der Regel schlecht für den Rechner auszuführen. Darum wird er in etwas überführt was die zur Ausführung nötigen Informationen in einer für den Rechner leicht ver- und abarbeitbaren Form enthält. Das ist dann irgendeine Art von Bytecode. Da fällt letztendlich auch Maschinensprache darunter, denn ein Prozessor ist im Grunde ein Bytecode-Interpreter der in Hardware gegossen ist.
Ein Sinn von Bytecode der (in der Regel) von einer virtuellen Maschine ausgeführt wird, ist der selbe wie von Hochsprachen: ein grösserer Abstraktionsgrad und komplexere Aktionen die man mit wenigen Anweisungen/Bytecode ausdrücken kann.
Was in .o-Dateien von C-Compilern tatsächlich drin steckt kann übrigens sehr unterschiedlich sein. AFAIK ist das nirgends standardisiert.
Ein Sinn von Bytecode der (in der Regel) von einer virtuellen Maschine ausgeführt wird, ist der selbe wie von Hochsprachen: ein grösserer Abstraktionsgrad und komplexere Aktionen die man mit wenigen Anweisungen/Bytecode ausdrücken kann.
Was in .o-Dateien von C-Compilern tatsächlich drin steckt kann übrigens sehr unterschiedlich sein. AFAIK ist das nirgends standardisiert.
-
- User
- Beiträge: 8
- Registriert: Dienstag 4. Februar 2014, 21:40
Gut, dann macht aber auch die Unterscheidung in Bytecode und Binärcode (und Maschinencode) keinen Sinn, weil ja alles von der CPU abgearbeitet werden kann, oder?
Natürlich gibt es da einen Unterschied. Ein Maschinencodebefehl besteht aus genau einem Befehl, welcher durch eine Maschine umgesetzt wird. Eine Bytecodeanweisung ist aber normalerweise aus mehreren Maschinencodebefehlen zusammengesetzt, bzw. wird durch mehrere Maschinencodebefehle umgesetzt.Diego Brei hat geschrieben:Gut, dann macht aber auch die Unterscheidung in Bytecode und Binärcode (und Maschinencode) keinen Sinn, weil ja alles von der CPU abgearbeitet werden kann, oder?
Das Leben ist wie ein Tennisball.
@Diego Brei: Die CPU kann nur den Bytecode/Maschinencode ausführen für den sie gebaut ist, aber man kann ja beliebige andere Bytecodeformate definieren die nicht direkt von der Hardware ausgeführt werden können. In sofern macht die Unterscheidung also doch Sinn.