Wie genau funktioniert der import-Bytecodebefehl?

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.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Wie genau funktioniert der import-Bytecodebefehl?

Beitragvon sma » Donnerstag 28. Februar 2008, 20:28

Ist vielleicht sehr speziell, aber möglicherweise weiß es jemand und ich muss mich nicht durch den C-Code von CPython wühlen. Übersetze ich

Code: Alles auswählen

import a

dann wird dieser Bytecode erzeugt:

Code: Alles auswählen

LOAD_CONST -1
LOAD_CONST None
IMPORT_NAME 'a'
STORE_FAST 'a'

Laut Dokumentation erwartet `IMPORT_NAME` aber nur einen String auf dem Stack, nicht drei Argumente. Was bedeuten also -1 und None?

Code: Alles auswählen

from a import b, c

wird in

Code: Alles auswählen

LOAD_CONST -1
LOAD_CONST ('b', 'c')
IMPORT_NAME 'a'
IMPORT_FROM 'b'
STORE_FAST 'b'
IMPORT_FROM 'c'
STORE_FAST 'c'
POP_TOP

übersetzt. Der zweite Parameter ist offenbar in diesem Fall nochmals die Liste der zu importierenden Namen. Wozu wird die benötigt? Und was soll die -1?

Stefan
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Beitragvon nkoehring » Donnerstag 28. Februar 2008, 22:48

Schau dir mal den Namespace an, nachdem du soetwas importiert hast...
BlackJack

Beitragvon BlackJack » Freitag 29. Februar 2008, 00:06

Er möchte wissen, *wie* der Bytecode das macht. *Was* er macht, hat sma schon verstanden.

Weder die -1 noch das Tupel machen auf den ersten Blick Sinn.
Benutzeravatar
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Re: Wie genau funktioniert der import-Bytecodebefehl?

Beitragvon mitsuhiko » Freitag 29. Februar 2008, 03:33

sma hat geschrieben:Was bedeuten also -1 und None?

-1: kein absoluter import (siehe from __future__ import absolute_import), 0 absolute imports. Das None ist das fromlist Argument für __import__.

Beim Unteren Import das gleiche, nur das das statt None jetzt ein Tuple ist. IMPORT_FROM macht soweit ich weiß nicht viel anders als getattr, deswegen das Tuple für das __import__ Callable, dass wie man ja weiß, vom User überschrieben werden kann.
TUFKAB – the user formerly known as blackbird
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Beitragvon sma » Samstag 1. März 2008, 12:17

mitsuhiko, danke. Ich verstehe jetzt die Zahl (die auch 1, 2, ... bei relativen Imports sein kann) und das Tupel wird wohl einfach übergeben, damit die __import__-Funktion weiß, was gleich danach aus dem Modul gezogen werden soll.

Ich bin ein bisschen irritiert, dass die Dokumentation von __import__ Listen als Beispiel nennt, obwohl der Interpreter intern Tupel benutzt. Überschreibe ich die Funktion und lasse mir anzeigen, was dort ankommt, sind es Tupel.

Imports in Python sind doch kniffeliger, als ich mir das so ohne wirkliches Studium der Sprachspezifikation zusammengereimt habe. Da muss ich wohl nochmal ran bei meinem Interpreter :(

Stefan
Benutzeravatar
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Beitragvon mitsuhiko » Montag 3. März 2008, 18:17

sma hat geschrieben:Imports in Python sind doch kniffeliger, als ich mir das so ohne wirkliches Studium der Sprachspezifikation zusammengereimt habe. Da muss ich wohl nochmal ran bei meinem Interpreter :(

Imports sind auch Sprachtechnisch etwas unsauber gelöst und nicht genau spezifiziert. IronPython kann zum Beispiel eine Menge Python Libraries nicht richtig importieren (darunter Pygments) weil es das Modul erst nach erfolgreicher Initialisierung in sys.modules unterbringt.
TUFKAB – the user formerly known as blackbird
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Beitragvon sma » Mittwoch 5. März 2008, 11:10

6.12. der Sprachspezifikation sagt aber recht eindeutig: "Otherwise, an empty module of the given name is created and inserted in the module table, and then the code block is executed in the context of this module". Damit macht IronPython es falsch, wenn sie das Modul-Objekt erst nach der Initialisierung in sys.modules einhängen.

Stefan

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]