Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > de.comp.lang.python > #6049 > unrolled thread

[Python-de] Pfade, Modulnamen und import-Statements

Started byMarc Haber <mh+python-de@zugschlus.de>
First post2024-05-04 13:12 +0200
Last post2025-01-26 21:21 +0100
Articles 16 — 7 participants

Back to article view | Back to de.comp.lang.python


Contents

  [Python-de] Pfade, Modulnamen und import-Statements Marc Haber <mh+python-de@zugschlus.de> - 2024-05-04 13:12 +0200
    [Python-de] Re: Pfade, Modulnamen und import-Statements Hartmut Goebel <h.goebel@crazy-compilers.com> - 2024-05-04 19:22 +0200
      [Python-de] Re: Pfade, Modulnamen und import-Statements Marc Haber <mh+python-de@zugschlus.de> - 2024-05-05 10:21 +0200
        Re: [Python-de] Re: Pfade, Modulnamen und import-Statements Bastian Blank <usenet@waldi.eu.org> - 2024-05-05 10:32 +0000
          [Python-de] Re: Pfade, Modulnamen und import-Statements Marc Haber <mh+python-de@zugschlus.de> - 2024-05-10 11:37 +0200
            [Python-de] Re: Pfade, Modulnamen und import-Statements Hartmut Goebel <h.goebel@crazy-compilers.com> - 2024-05-11 17:49 +0200
    Re: [Python-de] Pfade, Modulnamen und import-Statements "Peter J. Holzer" <hjp-usenet4@hjp.at> - 2024-05-05 02:26 +0200
      [Python-de] Re: Pfade, Modulnamen und import-Statements Marc Haber <mh+python-de@zugschlus.de> - 2024-05-05 10:25 +0200
        Re: [Python-de] Re: Pfade, Modulnamen und import-Statements "Peter J. Holzer" <hjp-usenet4@hjp.at> - 2024-05-05 12:38 +0200
          [Python-de] Re: Pfade, Modulnamen und import-Statements Marc Haber <mh+python-de@zugschlus.de> - 2024-05-10 11:39 +0200
            Re: [Python-de] Re: Pfade, Modulnamen und import-Statements "Peter J. Holzer" <hjp-usenet4@hjp.at> - 2024-05-10 19:25 +0200
    Re: [Python-de] Pfade, Modulnamen und import-Statements Hermann Riemann <nospam.ng@hermann-riemann.de> - 2024-05-05 12:02 +0200
      [Python-de] Re: Pfade, Modulnamen und import-Statements Marc Haber <mh+python-de@zugschlus.de> - 2024-05-05 12:35 +0200
    Re: [Python-de] Pfade, Modulnamen und import-Statements Hermann Riemann <nospam.ng@hermann-riemann.de> - 2024-05-10 20:05 +0200
      [Python-de] Re: Pfade, Modulnamen und import-Statements Christopher Arndt <chris@chrisarndt.de> - 2024-05-11 15:18 +0200
      [Python-de] Re: Pfade, Modulnamen und import-Statements Hartmut Goebel <h.goebel@goebel-consult.de> - 2025-01-26 21:21 +0100

#6049 — [Python-de] Pfade, Modulnamen und import-Statements

FromMarc Haber <mh+python-de@zugschlus.de>
Date2024-05-04 13:12 +0200
Subject[Python-de] Pfade, Modulnamen und import-Statements
Message-ID<ZjYYBgoIiqLkxkB3@torres.zugschlus.de>
Hallo,

ich hab mal eine Verständnisfrage.

Gegeben sei ein Verzeichnis . und ein Programm ./keks.
Weiterhin sei die Klasse MyClass1 in d/mc1.py und die Klasse MyClass2 in
d/mc2.py definierrt.

Wenn ich nun in keks die Klasse MyClass2 benutzen möchte, schreibe ich
"from d.mc2 import MyClass2". Wnn ich in d/mc1.py dasselbe tun möchte,
muss ich dort "from mc2 import MyClass2" schreiben, kann also Code, der
"verwandte" Module benutzt, nicht frei verschieben.

Ist das so gedacht, oder verpass ich da was?

Grüße
Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Leimen, Germany    |  lose things."    Winona Ryder | Fon: *49 6224 1600402
Nordisch by Nature |  How to make an American Quilt | Fax: *49 6224 1600421

[toc] | [next] | [standalone]


#6050 — [Python-de] Re: Pfade, Modulnamen und import-Statements

FromHartmut Goebel <h.goebel@crazy-compilers.com>
Date2024-05-04 19:22 +0200
Subject[Python-de] Re: Pfade, Modulnamen und import-Statements
Message-ID<a1b0c3e8-9e07-4cde-9b19-2bc800d51db0@crazy-compilers.com>
In reply to#6049
Am 04.05.24 um 13:12 schrieb Marc Haber:
> Wnn ich in d/mc1.py dasselbe tun möchte,
> muss ich dort "from mc2 import MyClass2" schreiben,

Ich vermute, Du musst "from ..mc2 import …" schreiben, da Du das Modul 
relativ zu mc1 "adressieren" musst. Falls es bei Dir ohne ".." ist 
irgendwas faul.

> kann also Code, der
> "verwandte" Module benutzt, nicht frei verschieben.
Ganz verstehe ich Deine Frage nicht, aber ich sag mal: Ja, das ist so 
gedacht. Woher sollte python denn sonst wissen, wo es "MyClass2" findet? 
Und in "keks" muss Du ja auch den "Pfad" zum Modul angeben - warum 
wollte das in einem Modul anders sein?

-- 
Regards
Hartmut Goebel

| Hartmut Goebel          |h.goebel@crazy-compilers.com                |
|www.crazy-compilers.com  | compilers which you thought are impossible |

[toc] | [prev] | [next] | [standalone]


#6052 — [Python-de] Re: Pfade, Modulnamen und import-Statements

FromMarc Haber <mh+python-de@zugschlus.de>
Date2024-05-05 10:21 +0200
Subject[Python-de] Re: Pfade, Modulnamen und import-Statements
Message-ID<ZjdBpXoZUmsZAWaG@torres.zugschlus.de>
In reply to#6050
On Sat, May 04, 2024 at 07:22:52PM +0200, Hartmut Goebel wrote:
> Am 04.05.24 um 13:12 schrieb Marc Haber:
> > Wnn ich in d/mc1.py dasselbe tun möchte,
> > muss ich dort "from mc2 import MyClass2" schreiben,
> 
> Ich vermute, Du musst "from ..mc2 import …" schreiben, da Du das Modul
> relativ zu mc1 "adressieren" musst. Falls es bei Dir ohne ".." ist irgendwas
> faul.

Das funktioniert so wie ich es geschrieben habe. Im etwas konkreteren
Fall:

[37/5247]mh@swivel:~/git/zg2dns $ grep -E 'class|import' get-root zg2dns/*
get-root:from zg2dns.rootdata import DNSRootDataParser
zg2dns/query.py:from rootdata import DNSRootDataParser
zg2dns/query.py:class Zg2DNSQuery:
zg2dns/rootdata.py:class DNSRootDataParser:

Sowohl der Code in zg2dns/query-py als auch der code in get-root
benutzen die Klasse DNSRootDataParser, und das funktioniert auch:

2 [38/5247]mh@swivel:~/git/zg2dns $ zg2dns/query.py
2024-05-05 10:07:50.360 | DEBUG    | __main__:<module>:309 - rootservers.get_ipv4_servers()=['198.41.0.4', '199.9.14.201', '192.33.4.12', '199.7.91.13', '192.203.230.10', '192.5.5.241', '192.112.36.4', '198.97.190.53', '192.36.148.17', '192.58.128.30', '193.0.14.129', '199.7.83.42', '202.12.27.33']
2024-05-05 10:07:50.360 | DEBUG    | __main__:<module>:310 - rootservers.get_ipv6_servers()=['2001:503:ba3e::2:30', '2001:500:200::b', '2001:500:2::c', '2001:500:2d::d', '2001:500:a8::e', '2001:500:2f::f', '2001:500:12::d0d', '2001:500:1::53', '2001:7fe::53', '2001:503:c27::2:30', '2001:7fd::1', '2001:500:9f::42', '2001:dc3::35']
2024-05-05 10:07:50.360 | DEBUG    | __main__:<module>:311 - rootservers.get_all_servers()=['198.41.0.4', '199.9.14.201', '192.33.4.12', '199.7.91.13', '192.203.230.10', '192.5.5.241', '192.112.36.4', '198.97.190.53', '192.36.148.17', '192.58.128.30', '193.0.14.129', '199.7.83.42', '202.12.27.33', '2001:503:ba3e::2:30', '2001:500:200::b', '2001:500:2::c', '2001:500:2d::d', '2001:500:a8::e', '2001:500:2f::f', '2001:500:12::d0d', '2001:500:1::53', '2001:7fe::53', '2001:503:c27::2:30', '2001:7fd::1', '2001:500:9f::42', '2001:dc3::35']
2024-05-05 10:07:50.361 | DEBUG    | __main__:<module>:312 - rootservers()=['198.41.0.4', '199.9.14.201', '192.33.4.12', '199.7.91.13', '192.203.230.10', '192.5.5.241', '192.112.36.4', '198.97.190.53', '192.36.148.17', '192.58.128.30', '193.0.14.129', '199.7.83.42', '202.12.27.33', '2001:503:ba3e::2:30', '2001:500:200::b', '2001:500:2::c', '2001:500:2d::d', '2001:500:a8::e', '2001:500:2f::f', '2001:500:12::d0d', '2001:500:1::53', '2001:7fe::53', '2001:503:c27::2:30', '2001:7fd::1', '2001:500:9f::42', '2001:dc3::35']
[39/5247]mh@swivel:~/git/zg2dns $ ./get-root
IPv4 Root Servers: ['198.41.0.4', '199.9.14.201', '192.33.4.12', '199.7.91.13', '192.203.230.10', '192.5.5.241', '192.112.36.4', '198.97.190.53', '192.36.148.17', '192.58.128.30', '193.0.14.129', '199.7.83.42', '202.12.27.33']
IPv6 Root Servers: ['2001:503:ba3e::2:30', '2001:500:200::b', '2001:500:2::c', '2001:500:2d::d', '2001:500:a8::e', '2001:500:2f::f', '2001:500:12::d0d', '2001:500:1::53', '2001:7fe::53', '2001:503:c27::2:30', '2001:7fd::1', '2001:500:9f::42', '2001:dc3::35']
All Root Servers: ['198.41.0.4', '199.9.14.201', '192.33.4.12', '199.7.91.13', '192.203.230.10', '192.5.5.241', '192.112.36.4', '198.97.190.53', '192.36.148.17', '192.58.128.30', '193.0.14.129', '199.7.83.42', '202.12.27.33', '2001:503:ba3e::2:30', '2001:500:200::b', '2001:500:2::c', '2001:500:2d::d', '2001:500:a8::e','2001:500:2f::f', '2001:500:12::d0d', '2001:500:1::53', '2001:7fe::53', '2001:503:c27::2:30', '2001:7fd::1', '2001:500:9f::42', '2001:dc3::35']
All Root Servers: ['198.41.0.4', '199.9.14.201', '192.33.4.12', '199.7.91.13', '192.203.230.10', '192.5.5.241', '192.112.36.4', '198.97.190.53', '192.36.148.17', '192.58.128.30', '193.0.14.129', '199.7.83.42', '202.12.27.33', '2001:503:ba3e::2:30', '2001:500:200::b', '2001:500:2::c', '2001:500:2d::d', '2001:500:a8::e','2001:500:2f::f', '2001:500:12::d0d', '2001:500:1::53', '2001:7fe::53', '2001:503:c27::2:30', '2001:7fd::1', '2001:500:9f::42', '2001:dc3::35']
[40/5247]mh@swivel:~/git/zg2dns $

Die Notation ..irgendwas ist also nicht notwendig.

> > kann also Code, der
> > "verwandte" Module benutzt, nicht frei verschieben.
> Ganz verstehe ich Deine Frage nicht, aber ich sag mal: Ja, das ist so
> gedacht. Woher sollte python denn sonst wissen, wo es "MyClass2" findet? Und
> in "keks" muss Du ja auch den "Pfad" zum Modul angeben - warum wollte das in
> einem Modul anders sein?

Ich finde es wenig schön dass man abhängig vom Ort der Nutzung
unterschiedliche Import-Statements schreiben muss, aber wenn das so ist
kann ich damit leben. Ich hatte das Verhalten halt nicht für pythonisch
gehalten.

In dnspython ist das auch nicht so geschrieben, z.B. steht in
/usr/lib/python3/dist-packages/dns/resolver.py immer das Predix dns in
den Imports dabei. Das funktioniert vermutlich, weil
/usr/lib/python3/dist-packages im Pythonpath steht.

Wäre ich dnspython-Entwickler, hätte ich ja meine workingcopy von mir
aus unter ~/git/dnspython ausgecheckt, und wenn ich irgendwas
ausprobiere, würde das "import dns.query" in
~/git/dnspython/dns/resolver.py ja das dns/query.py aus dem Pythonpath
anziehen und nicht das aus meiner Workingcopy, weil ich ja sicher auch
die Releaseversion der Library installiert hätte.

Wir arbeiten Modulentwicker in so einer Situation?

Grüße
Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Leimen, Germany    |  lose things."    Winona Ryder | Fon: *49 6224 1600402
Nordisch by Nature |  How to make an American Quilt | Fax: *49 6224 1600421

[toc] | [prev] | [next] | [standalone]


#6055 — Re: [Python-de] Re: Pfade, Modulnamen und import-Statements

FromBastian Blank <usenet@waldi.eu.org>
Date2024-05-05 10:32 +0000
SubjectRe: [Python-de] Re: Pfade, Modulnamen und import-Statements
Message-ID<slrnv3eo1s.mt.usenet@mobilewave.waldi.eu.org>
In reply to#6052
Marc Haber wrote:
> [37/5247]mh@swivel:~/git/zg2dns $ grep -E 'class|import' get-root zg2dns/*
> get-root:from zg2dns.rootdata import DNSRootDataParser
> zg2dns/query.py:from rootdata import DNSRootDataParser
> zg2dns/query.py:class Zg2DNSQuery:
> zg2dns/rootdata.py:class DNSRootDataParser:

Versuche mal "zg2dns.query" zu importieren:

| Traceback (most recent call last):
|   File "/tmp/t/test", line 3, in <module>
|     import zg2dns.query
|   File "/tmp/t/zg2dns/query.py", line 1, in <module>
|     from rootdata import DNSRootDataParser
| ModuleNotFoundError: No module named 'rootdata'

> Ich finde es wenig schön dass man abhängig vom Ort der Nutzung
> unterschiedliche Import-Statements schreiben muss, aber wenn das so ist
> kann ich damit leben. Ich hatte das Verhalten halt nicht für pythonisch
> gehalten.

Dein Fehler ist ein komplett anderer.

Der Python-Interpreter fügt das Verzeichnis, in dem das aktuelle Script
liegt, dem Suchpfad hinzu.

Rufst du "get-root" auf, dann ist es ".". Damit findet "import
zg2dns.rootdata" auch "zg2dns/rootdata.py".

Rufst du aber "zg2dns/query.py" direkt auf, dann ist auf einmal
das Verzeichnis "zg2dns" im Suchpfad. Also referenziert "import
rootdata" auf einmal was anderes.

> Wäre ich dnspython-Entwickler, hätte ich ja meine workingcopy von mir
> aus unter ~/git/dnspython ausgecheckt, und wenn ich irgendwas
> ausprobiere, würde das "import dns.query" in
> ~/git/dnspython/dns/resolver.py ja das dns/query.py aus dem Pythonpath
> anziehen und nicht das aus meiner Workingcopy, weil ich ja sicher auch
> die Releaseversion der Library installiert hätte.

Dafür gibt es "pip install -e ." z.B. Damit macht man das aktuelle
Projekt im globalen Suchpfad des benutzten Interpreters verfügbar.

> Wir arbeiten Modulentwicker in so einer Situation?

Module werden nicht als Scripte direkt aufgerufen, sind also auch nie
ausführbar. Statt dessen werden sie mittels "python3 -m" aufgerufen.

Im nächsten Schritt kommen dann Entry-Points, aus denen dann Scripte
entstehen, welche in $prefix/bin landen.

Bastian

[toc] | [prev] | [next] | [standalone]


#6059 — [Python-de] Re: Pfade, Modulnamen und import-Statements

FromMarc Haber <mh+python-de@zugschlus.de>
Date2024-05-10 11:37 +0200
Subject[Python-de] Re: Pfade, Modulnamen und import-Statements
Message-ID<Zj3q0Y19HfBbszdv@torres.zugschlus.de>
In reply to#6055
On Sun, May 05, 2024 at 10:32:28AM -0000, Bastian Blank wrote:
> Marc Haber wrote:
> > [37/5247]mh@swivel:~/git/zg2dns $ grep -E 'class|import' get-root zg2dns/*
> > get-root:from zg2dns.rootdata import DNSRootDataParser
> > zg2dns/query.py:from rootdata import DNSRootDataParser
> > zg2dns/query.py:class Zg2DNSQuery:
> > zg2dns/rootdata.py:class DNSRootDataParser:
> 
> Versuche mal "zg2dns.query" zu importieren

Wo?

> Der Python-Interpreter fügt das Verzeichnis, in dem das aktuelle Script
> liegt, dem Suchpfad hinzu.
> 
> Rufst du "get-root" auf, dann ist es ".". Damit findet "import
> zg2dns.rootdata" auch "zg2dns/rootdata.py".
> 
> Rufst du aber "zg2dns/query.py" direkt auf, dann ist auf einmal
> das Verzeichnis "zg2dns" im Suchpfad. Also referenziert "import
> rootdata" auf einmal was anderes.

Also muss ich abhängig von dem Ort wo mein Skript liegt unterschiedliche
import-Statements benutzen, das finde ich mindestens unschön. Aber jetzt
wo ich es weiß kann ich aes natürlich machen.

> Dafür gibt es "pip install -e ." z.B. Damit macht man das aktuelle
> Projekt im globalen Suchpfad des benutzten Interpreters verfügbar.

Aber hoffentlich nur im Environment einer Subshell? Oder ist das
persistentes Herumfummeln im System? Wenn ja, wo?

> > Wir arbeiten Modulentwicker in so einer Situation?
> 
> Module werden nicht als Scripte direkt aufgerufen, sind also auch nie
> ausführbar. Statt dessen werden sie mittels "python3 -m" aufgerufen.

Das Python Tutorial Kapitel 6.1.1 "Executing modules as scripts" stelt
das als ganz praktisches Feature dar.

Grüße
Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Leimen, Germany    |  lose things."    Winona Ryder | Fon: *49 6224 1600402
Nordisch by Nature |  How to make an American Quilt | Fax: *49 6224 1600421

[toc] | [prev] | [next] | [standalone]


#6066 — [Python-de] Re: Pfade, Modulnamen und import-Statements

FromHartmut Goebel <h.goebel@crazy-compilers.com>
Date2024-05-11 17:49 +0200
Subject[Python-de] Re: Pfade, Modulnamen und import-Statements
Message-ID<f1a959a6-c758-45d5-ac28-7484813106a2@crazy-compilers.com>
In reply to#6059
Am 10.05.24 um 11:37 schrieb Marc Haber:
>> Dafür gibt es "pip install -e ." z.B. Damit macht man das aktuelle
>> Projekt im globalen Suchpfad des benutzten Interpreters verfügbar.
> Aber hoffentlich nur im Environment einer Subshell? Oder ist das
> persistentes Herumfummeln im System? Wenn ja, wo?

pip install installiert per default nach 
/usr/lib/pythonX.YZ/site-packages. Debian lässt das aber gar nicht mehr zu.

Wenn ein virtual environment aktiv ist, wird nach 
<venv>/lib/pythonX.YZ/site-packages installliert. Dito bei nicht-aktivem 
vend und "<venv>/bin/pip install".

Option --user installiert nach $HOME/.local/lib/pythonX.YZ/site-packages.

pip list zeigt Dir, was wo installiert ist. (Bei aktivem venv aber im 
venv und nicht im System.)

-- 
Regards
Hartmut Goebel

| Hartmut Goebel          |h.goebel@crazy-compilers.com                |
|www.crazy-compilers.com  | compilers which you thought are impossible |

[toc] | [prev] | [next] | [standalone]


#6051

From"Peter J. Holzer" <hjp-usenet4@hjp.at>
Date2024-05-05 02:26 +0200
Message-ID<slrnv3dkgq.14mcq.hjp-usenet4@trintignant.hjp.at>
In reply to#6049
On 2024-05-04 11:12, Marc Haber <mh+python-de@zugschlus.de> wrote:
> ich hab mal eine Verständnisfrage.
>
> Gegeben sei ein Verzeichnis . und ein Programm ./keks.
> Weiterhin sei die Klasse MyClass1 in d/mc1.py und die Klasse MyClass2 in
> d/mc2.py definierrt.
>
> Wenn ich nun in keks die Klasse MyClass2 benutzen möchte, schreibe ich
> "from d.mc2 import MyClass2". Wnn ich in d/mc1.py dasselbe tun möchte,
> muss ich dort "from mc2 import MyClass2" schreiben,

Nein, das funktioniert nicht:

#v+
% ./keks
Traceback (most recent call last):
  File "/home/hjp/tmp/marc/./keks", line 3, in <module>
    from d.mc1 import MyClass1
  File "/home/hjp/tmp/marc/d/mc1.py", line 1, in <module>
    from mc2 import MyClass2
ModuleNotFoundError: No module named 'mc2'
#v-

Es muss

#v+
from d.mc2 import MyClass2
#v-

heißen. Ob Du das Modul von keks oder von einem anderen Modul aus
importierst, macht keinen Unterschied.

> kann also Code, der
> "verwandte" Module benutzt, nicht frei verschieben.
>
> Ist das so gedacht, oder verpass ich da was?

Wie Hartmut schon geschrieben hat, kannst
Du relative Imports verwendenm, hier also

#v+
from .mc2 import MyClass2
#v-

Ob das für Deinen Code sinnvoll ist, musst du selbst entscheiden.

        hp

[toc] | [prev] | [next] | [standalone]


#6053 — [Python-de] Re: Pfade, Modulnamen und import-Statements

FromMarc Haber <mh+python-de@zugschlus.de>
Date2024-05-05 10:25 +0200
Subject[Python-de] Re: Pfade, Modulnamen und import-Statements
Message-ID<ZjdCdg94EQs3zPul@torres.zugschlus.de>
In reply to#6051
On Sun, May 05, 2024 at 02:26:02AM +0200, Peter J. Holzer wrote:
> On 2024-05-04 11:12, Marc Haber <mh+python-de@zugschlus.de> wrote:
> > ich hab mal eine Verständnisfrage.
> >
> > Gegeben sei ein Verzeichnis . und ein Programm ./keks.
> > Weiterhin sei die Klasse MyClass1 in d/mc1.py und die Klasse MyClass2 in
> > d/mc2.py definierrt.
> >
> > Wenn ich nun in keks die Klasse MyClass2 benutzen möchte, schreibe ich
> > "from d.mc2 import MyClass2". Wnn ich in d/mc1.py dasselbe tun möchte,
> > muss ich dort "from mc2 import MyClass2" schreiben,
> 
> Nein, das funktioniert nicht:
> 
> #v+
> % ./keks
> Traceback (most recent call last):
>   File "/home/hjp/tmp/marc/./keks", line 3, in <module>
>     from d.mc1 import MyClass1
>   File "/home/hjp/tmp/marc/d/mc1.py", line 1, in <module>
>     from mc2 import MyClass2
> ModuleNotFoundError: No module named 'mc2'
> #v-

Mein mc1.py hat eingebauten testcode:

#v+
if __name__ == "__main__":
    zdns = Zg2DNSQuery(timeout=2, debug=True)
    
    rootservers = DNSRootDataParser()
    logger.debug(f"{rootservers.get_ipv4_servers()=}")
#v-

verhält sich der vielleicht anders als wenn man nur das Modul
importiert? Das wäre dann ja noch viel schlimmer ;-)

Grüße
Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Leimen, Germany    |  lose things."    Winona Ryder | Fon: *49 6224 1600402
Nordisch by Nature |  How to make an American Quilt | Fax: *49 6224 1600421

[toc] | [prev] | [next] | [standalone]


#6056 — Re: [Python-de] Re: Pfade, Modulnamen und import-Statements

From"Peter J. Holzer" <hjp-usenet4@hjp.at>
Date2024-05-05 12:38 +0200
SubjectRe: [Python-de] Re: Pfade, Modulnamen und import-Statements
Message-ID<slrnv3eocq.16cpt.hjp-usenet4@trintignant.hjp.at>
In reply to#6053
On 2024-05-05 08:25, Marc Haber <mh+python-de@zugschlus.de> wrote:
> On Sun, May 05, 2024 at 02:26:02AM +0200, Peter J. Holzer wrote:
>> On 2024-05-04 11:12, Marc Haber <mh+python-de@zugschlus.de> wrote:
>> > ich hab mal eine Verständnisfrage.
>> >
>> > Gegeben sei ein Verzeichnis . und ein Programm ./keks.
>> > Weiterhin sei die Klasse MyClass1 in d/mc1.py und die Klasse MyClass2 in
>> > d/mc2.py definierrt.
>> >
>> > Wenn ich nun in keks die Klasse MyClass2 benutzen möchte, schreibe ich
>> > "from d.mc2 import MyClass2". Wnn ich in d/mc1.py dasselbe tun möchte,
>> > muss ich dort "from mc2 import MyClass2" schreiben,
>> 
>> Nein, das funktioniert nicht:
>> 
>> #v+
>> % ./keks
>> Traceback (most recent call last):
>>   File "/home/hjp/tmp/marc/./keks", line 3, in <module>
>>     from d.mc1 import MyClass1
>>   File "/home/hjp/tmp/marc/d/mc1.py", line 1, in <module>
>>     from mc2 import MyClass2
>> ModuleNotFoundError: No module named 'mc2'
>> #v-
>
> Mein mc1.py hat eingebauten testcode:
>
> #v+
> if __name__ == "__main__":
>     zdns = Zg2DNSQuery(timeout=2, debug=True)
>     
>     rootservers = DNSRootDataParser()
>     logger.debug(f"{rootservers.get_ipv4_servers()=}")
> #v-

Ah, dachte ich mir, dass da eine wichtige Information fehlt ;-).


> verhält sich der vielleicht anders als wenn man nur das Modul
> importiert? Das wäre dann ja noch viel schlimmer ;-)

Wenn Du ein Script aufrufst, wird das Directory des Scripts in sys.path
eingefügt. Dadurch wird dann bei einem "import m" u.a. auch nach
"full_path_to_script_dir/m.py" gesucht und damit funktioniert der
Import.

Zum Testen von komplexeren Packages ist das aber wenig hilfreich, weil
im echten Einsatz natürlich nicht irgendwelche Subdirectorys der
Package-Hierarchie im Suchpfad stehen und man, wenn man ein Modul aus
einem Package direkt aufruft, die Package-Hierarchie verliert und damit
relative Imports nicht funktionieren:

#v+
% python3 d/mc1.py
__main__ ['/home/hjp/tmp/marc/d', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/home/hjp/.local/lib/python3.10/site-packages', '/usr/local/lib/python3.10/dist-packages', '/usr/lib/python3/dist-packages']
Traceback (most recent call last):
  File "/home/hjp/tmp/marc/d/mc1.py", line 4, in <module>
    from .mc2 import MyClass2
ImportError: attempted relative import with no known parent package
#v-

Unter anderem auch aus diesem Grund schreibe ich Test-Code immer in
eigene Files.

        hp

[toc] | [prev] | [next] | [standalone]


#6060 — [Python-de] Re: Pfade, Modulnamen und import-Statements

FromMarc Haber <mh+python-de@zugschlus.de>
Date2024-05-10 11:39 +0200
Subject[Python-de] Re: Pfade, Modulnamen und import-Statements
Message-ID<Zj3rZAstdShbMuSt@torres.zugschlus.de>
In reply to#6056
On Sun, May 05, 2024 at 12:38:18PM +0200, Peter J. Holzer wrote:
> On 2024-05-05 08:25, Marc Haber <mh+python-de@zugschlus.de> wrote:
> > On Sun, May 05, 2024 at 02:26:02AM +0200, Peter J. Holzer wrote:
> >> On 2024-05-04 11:12, Marc Haber <mh+python-de@zugschlus.de> wrote:
> >> > ich hab mal eine Verständnisfrage.
> >> >
> >> > Gegeben sei ein Verzeichnis . und ein Programm ./keks.
> >> > Weiterhin sei die Klasse MyClass1 in d/mc1.py und die Klasse MyClass2 in
> >> > d/mc2.py definierrt.
> >> >
> >> > Wenn ich nun in keks die Klasse MyClass2 benutzen möchte, schreibe ich
> >> > "from d.mc2 import MyClass2". Wnn ich in d/mc1.py dasselbe tun möchte,
> >> > muss ich dort "from mc2 import MyClass2" schreiben,
> >> 
> >> Nein, das funktioniert nicht:
> >> 
> >> #v+
> >> % ./keks
> >> Traceback (most recent call last):
> >>   File "/home/hjp/tmp/marc/./keks", line 3, in <module>
> >>     from d.mc1 import MyClass1
> >>   File "/home/hjp/tmp/marc/d/mc1.py", line 1, in <module>
> >>     from mc2 import MyClass2
> >> ModuleNotFoundError: No module named 'mc2'
> >> #v-
> >
> > Mein mc1.py hat eingebauten testcode:
> >
> > #v+
> > if __name__ == "__main__":
> >     zdns = Zg2DNSQuery(timeout=2, debug=True)
> >     
> >     rootservers = DNSRootDataParser()
> >     logger.debug(f"{rootservers.get_ipv4_servers()=}")
> > #v-
> 
> Ah, dachte ich mir, dass da eine wichtige Information fehlt ;-).

Welche? Dass ich den Empfehlungen des Python Tutorials, Kapitel 6.1.1
"Executing modules as scripts" gefolgt bin? War das falsch?

> Unter anderem auch aus diesem Grund schreibe ich Test-Code immer in
> eigene Files.

So werde ich das dann jetzt wohl auch halten. Schade.

Grüße
Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Leimen, Germany    |  lose things."    Winona Ryder | Fon: *49 6224 1600402
Nordisch by Nature |  How to make an American Quilt | Fax: *49 6224 1600421

[toc] | [prev] | [next] | [standalone]


#6061 — Re: [Python-de] Re: Pfade, Modulnamen und import-Statements

From"Peter J. Holzer" <hjp-usenet4@hjp.at>
Date2024-05-10 19:25 +0200
SubjectRe: [Python-de] Re: Pfade, Modulnamen und import-Statements
Message-ID<slrnv3sm4l.1tos.hjp-usenet4@trintignant.hjp.at>
In reply to#6060
On 2024-05-10 09:39, Marc Haber <mh+python-de@zugschlus.de> wrote:
> On Sun, May 05, 2024 at 12:38:18PM +0200, Peter J. Holzer wrote:
>> Ah, dachte ich mir, dass da eine wichtige Information fehlt ;-).
>
> Welche?

Die Information, dass Du das gleiche Python-File einmal mittels import
und einmal als Script ausführst.

Das sind unterschiedliche Mechanismen.

> Dass ich den Empfehlungen des Python Tutorials, Kapitel 6.1.1
> "Executing modules as scripts" gefolgt bin? War das falsch?

Das funktioniert in einigen einfachen Fällen (insbesondere, wenn das
Modul keine weiteren Imports (außer Standard-Modulen) hat oder wenn die
alle direkt im Suchpfad liegen. Wenn man das mit einem Submodul eines
Packages probiert, muss man sich das Environment entsprechend herrichten
(z.B. indem man $PYTHONPATH passend setzt). Keine große Hexerei, wenn
man es weiß, aber selbst dann vergisst man gerne darauf (ich zumindest).
Ich würde daher davon abraten.

        hp

[toc] | [prev] | [next] | [standalone]


#6054

FromHermann Riemann <nospam.ng@hermann-riemann.de>
Date2024-05-05 12:02 +0200
Message-ID<l9p3pqFr2biU1@mid.individual.net>
In reply to#6049
Am 04.05.24 um 13:12 schrieb Marc Haber:

> ich hab mal eine Verständnisfrage.
> 
> Gegeben sei ein Verzeichnis . und ein Programm ./keks.
> Weiterhin sei die Klasse MyClass1 in d/mc1.py und die Klasse MyClass2 in
> d/mc2.py definierrt.
> 
> Wenn ich nun in keks die Klasse MyClass2 benutzen möchte, schreibe ich
> "from d.mc2 import MyClass2". Wnn ich in d/mc1.py dasselbe tun möchte,
> muss ich dort "from mc2 import MyClass2" schreiben, kann also Code, der
> "verwandte" Module benutzt, nicht frei verschieben.
> 
> Ist das so gedacht, oder verpass ich da was?

Bei Pfadproblemen verwende ich sys.path.append(

Hermann
    der das #include ../ich.h für gemeinsames vermisst.

-- 
<http://www.hermann-riemann.de>

[toc] | [prev] | [next] | [standalone]


#6057 — [Python-de] Re: Pfade, Modulnamen und import-Statements

FromMarc Haber <mh+python-de@zugschlus.de>
Date2024-05-05 12:35 +0200
Subject[Python-de] Re: Pfade, Modulnamen und import-Statements
Message-ID<ZjdhC_OIf0zEq7co@torres.zugschlus.de>
In reply to#6054
On Sun, May 05, 2024 at 12:02:34PM +0200, Hermann Riemann wrote:
> Bei Pfadproblemen verwende ich sys.path.append(

In Klassen- und Moduldefinitionen und importen? Echt jetzt?

Oder hast Du nur die Frage nicht verstanden?

Grüße
Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Leimen, Germany    |  lose things."    Winona Ryder | Fon: *49 6224 1600402
Nordisch by Nature |  How to make an American Quilt | Fax: *49 6224 1600421

[toc] | [prev] | [next] | [standalone]


#6062

FromHermann Riemann <nospam.ng@hermann-riemann.de>
Date2024-05-10 20:05 +0200
Message-ID<la7604FdslU1@mid.individual.net>
In reply to#6049
Am 04.05.24 um 13:12 schrieb Marc Haber:

> ich hab mal eine Verständnisfrage.
> 
> Gegeben sei ein Verzeichnis . und ein Programm ./keks.
> Weiterhin sei die Klasse MyClass1 in d/mc1.py und die Klasse MyClass2 in
> d/mc2.py definierrt.
> 
> Wenn ich nun in keks die Klasse MyClass2 benutzen möchte, schreibe ich
> "from d.mc2 import MyClass2". Wenn ich in d/mc1.py dasselbe tun möchte,
> muss ich dort "from mc2 import MyClass2" schreiben, kann also Code, der
> "verwandte" Module benutzt, nicht frei verschieben.
> 
> Ist das so gedacht, oder verpass ich da was?

Ein wenig lässt sich mit sys.path.append erreichen.

Ich benutze das für meine Hilfsprogramme,
die von mehreren Programme verwendet werden.

-- 
<http://www.hermann-riemann.de>

[toc] | [prev] | [next] | [standalone]


#6065 — [Python-de] Re: Pfade, Modulnamen und import-Statements

FromChristopher Arndt <chris@chrisarndt.de>
Date2024-05-11 15:18 +0200
Subject[Python-de] Re: Pfade, Modulnamen und import-Statements
Message-ID<da75dfec-7c23-4093-af02-a7d1b41cd2bf@chrisarndt.de>
In reply to#6062
Am 11.05.24 um 15:05 schrieb Stefan Ram:>    ODER ich habe "setuptools" 
mit "distutils" verwechselt, und
>    "setuptools" wurden in Python 3.12 nicht entfernt.

distutils wurde in 31.2 aus der stdlib entfernt.

setuptools war noch nie Teil der stdlib, wurde aber standardmäßig von 
venv in neue virtuelle Environments installiert. Das ist jetzt nicht 
mehr so.

Wenn man weiter distutils oder setuptools und eine setup.py verwenden 
will, sollte man daher eine pyproject.toml anlegen und eine
entsprechende [build-system] Sektion einfügen, die dafür sorgt, dass 
beim Bauen eines Pakets setuptools heruntergeladen wird setuptools hat 
dann seine eigene Version von distutils.

Siehe:

https://packaging.python.org/en/latest/tutorials/packaging-projects/#choosing-a-build-backend


Chris

[toc] | [prev] | [next] | [standalone]


#6254 — [Python-de] Re: Pfade, Modulnamen und import-Statements

FromHartmut Goebel <h.goebel@goebel-consult.de>
Date2025-01-26 21:21 +0100
Subject[Python-de] Re: Pfade, Modulnamen und import-Statements
Message-ID<913de228-0080-4702-b74b-d2a1ea476d9a@goebel-consult.de>
In reply to#6062
Am 26.01.25 um 20:55 schrieb Stefan Ram:
>    Nun, "module.py" als Skript starten, und es gibt eine Fehlermeldung!
>    Warum? Weil Python das Verzeichnis "package" nicht als Package sieht.

Nicht ganz.

Neuere Versionen von Python (3.10, evtl. schon früher) betrachten ein 
Verzeichnis auch ohne __init__.py als Package.

Aber "python package/module.py" startet die Datei eben - wie Du 
schreibst - als Skript. Und Skript können keine relativen Importe 
enthalten. Eben weil sie Skripte und keine Module eines Packages sind.

Du könntest allerdings das Module "package.module" ausführen, das geht:

python -m package.module

-- 
Schönen Gruß
Hartmut Goebel
Dipl.-Informatiker (univ), CISSP, CSSLP, ISO 27001 Lead Implementer
Information Security Management, Security Governance, Secure Software 
Development

Goebel Consult, Landshut
http://www.goebel-consult.de

Blog: https://www.goebel-consult.de/blog/2019/blockchain-bringts-nicht/
Kolumne: 
https://www.goebel-consult.de/blog/cissp-gefluester/2011-10-aus-der-schublade-in-die-koepfe/ 

[toc] | [prev] | [standalone]


Back to top | Article view | de.comp.lang.python


csiph-web