Wo verstecken sich die Funktionen in den Modulen?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Diego Brei
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?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

In specifications, Murphy's Law supersedes Ohm's.
Diego Brei
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?
BlackJack

@Diego Brei: Folge dem Link den Pillmuncher gepostet hat. Das Modul ist in C impementiert und nicht in Python.
Diego Brei
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.
Benutzeravatar
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.
BlackJack

@Diego Brei: Also bei mir ist es direkt mit in den Interpreter einkompiliert:

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')
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.
Diego Brei
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.
Benutzeravatar
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.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@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.
Diego Brei
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?
Benutzeravatar
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:

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
BlackJack

@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.
Diego Brei
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?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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?
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.
Das Leben ist wie ein Tennisball.
BlackJack

@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.
Antworten