Importazioni relative in Python 3


714

Voglio importare una funzione da un altro file nella stessa directory.

A volte funziona con me, from .mymodule import myfunctionma a volte ottengo un:

SystemError: Parent module '' not loaded, cannot perform relative import

A volte funziona from mymodule import myfunction, ma a volte ottengo anche un:

SystemError: Parent module '' not loaded, cannot perform relative import

Non capisco la logica qui e non sono riuscito a trovare alcuna spiegazione. Sembra completamente casuale.

Qualcuno potrebbe spiegarmi qual è la logica dietro tutto questo?


76
Questo significa che stai eseguendo un modulo all'interno del pacchetto come script. Esegui solo script dall'esterno del pacchetto.
Martijn Pieters

3
Probabilmente dovresti definire le condizioni in cui hai quelle "a volte" che menzioni. Capisco che non significa che hai errori casuali.
Joaquin,

15
@MartijnPieters: beh, sfortunatamente, questo modulo deve essere all'interno del pacchetto e, a volte, deve anche essere eseguibile come script. Hai idea di come potrei farlo?
John Smith Facoltativo

22
@JohnSmithOptional: mescolare gli script all'interno dei pacchetti è complicato e dovrebbe essere evitato, se possibile. Utilizzare uno script wrapper che importa il pacchetto ed esegue invece la funzione 'scripty'.
Martijn Pieters

3
Sembra sfortunato. Ho creato un modulo di base con classi / metodi che possono analizzare / analizzare un determinato tipo di file e ho anche (principalmente per me stesso) moduli secondari e script separati che lo importano - questi possono massaggiare / convertire quei file. Ma mi piace anche essere in grado di consegnare quel singolo file core (non un intero pacchetto complesso) all'utente finale in modo che possano facilmente posizionarlo vicino al loro file ed eseguirlo. In quella "modalità script", analizza e analizza il file e la codifica, raccoglie vari campi / valori / caratteri speciali e fornisce un rapporto. Ma in realtà non modifica il file. Anti-modello?
Jon Coombs,

Risposte:


528

sfortunatamente, questo modulo deve essere all'interno del pacchetto e, a volte, deve anche essere eseguibile come script. Hai idea di come potrei farlo?

È abbastanza comune avere un layout come questo ...

main.py
mypackage/
    __init__.py
    mymodule.py
    myothermodule.py

... con un mymodule.pysimile ...

#!/usr/bin/env python3

# Exported function
def as_int(a):
    return int(a)

# Test function for module  
def _test():
    assert as_int('1') == 1

if __name__ == '__main__':
    _test()

... myothermodule.pycome questo ...

#!/usr/bin/env python3

from .mymodule import as_int

# Exported function
def add(a, b):
    return as_int(a) + as_int(b)

# Test function for module  
def _test():
    assert add('1', '1') == 2

if __name__ == '__main__':
    _test()

... e main.pycosì ...

#!/usr/bin/env python3

from mypackage.myothermodule import add

def main():
    print(add('1', '1'))

if __name__ == '__main__':
    main()

... che funziona bene quando si esegue main.pyo mypackage/mymodule.py, ma non riesce mypackage/myothermodule.py, a causa della relativa importazione ...

from .mymodule import as_int

Il modo in cui dovresti correre è ...

python3 -m mypackage.myothermodule

... ma è un po 'prolisso, e non si mescola bene con una linea di shebang come #!/usr/bin/env python3.

La soluzione più semplice per questo caso, supponendo che il nome mymodulesia univoco a livello globale, sarebbe quella di evitare l'uso delle importazioni relative e usare solo ...

from mymodule import as_int

... anche se, se non è univoco, o se la struttura del pacchetto è più complessa, dovrai includere la directory contenente la directory del pacchetto PYTHONPATHe farlo in questo modo ...

from mypackage.mymodule import as_int

... o se vuoi che funzioni "out of the box", puoi prima cercare il PYTHONPATHcodice in con questo ...

import sys
import os

PACKAGE_PARENT = '..'
SCRIPT_DIR = os.path.dirname(os.path.realpath(os.path.join(os.getcwd(), os.path.expanduser(__file__))))
sys.path.append(os.path.normpath(os.path.join(SCRIPT_DIR, PACKAGE_PARENT)))

from mypackage.mymodule import as_int

È una specie di dolore, ma c'è un indizio sul perché in una e-mail scritta da un certo Guido van Rossum ...

Sono -1 su questo e su tutti gli altri proposti twiddling della __main__ macchina. L'unico caso d'uso sembra essere l'esecuzione di script che si trovano all'interno della directory di un modulo, che ho sempre visto come un antipattern. Per farmi cambiare idea, dovresti convincermi che non lo è.

Che l'esecuzione di script all'interno di un pacchetto sia un antipattern o meno è soggettivo, ma personalmente lo trovo davvero utile in un pacchetto che ho contenente alcuni widget personalizzati di wxPython, quindi posso eseguire lo script per qualsiasi file sorgente per visualizzare un wx.Framesolo contenuto quel widget a scopo di test.


7
Un modo migliore per ottenere SCRIPTDIR è dato in un commento sull'importazione di un modulo da un percorso relativo, come os.path.realpath(os.path.dirname(inspect.getfile(inspect.currentframe())))se filefossi sicuro che il tuo modulo abbia sempre un valore corretto che potresti usare os.path.realpath(os.path.dirname(__file__)).
marcz,

2
Puoi espandere PYTHONPATH applicando uno snippet di codice più breve e leggibile: sys.path.append( os.path.join( os.path.dirname(__file__), os.path.pardir ) )
Alex-Bogdanov,

12
...which I've always seen as an antipattern.Non vedo come sia un modello anti ... Sembra che sarebbe molto conveniente semplicemente far funzionare intuitivamente le relative importazioni. Voglio solo essere in grado di importare cose che so siano nella stessa directory. Mi chiedo quale fosse il suo ragionamento
YungGun,

9
Guido colpisce ancora: eliminare cose che avrebbero potuto essere utili. Bene, non succederà più.
javadba,

4
Questa è la cosa più triste che abbia mai visto su Python.
AtilioA

263

Spiegazione

Dal PEP 328

Le importazioni relative utilizzano l'attributo __name__ di un modulo per determinare la posizione di quel modulo nella gerarchia dei pacchetti. Se il nome del modulo non contiene alcuna informazione sul pacchetto (ad es. È impostato su '__main__'), le importazioni relative vengono risolte come se il modulo fosse un modulo di livello superiore , indipendentemente da dove si trova effettivamente il modulo sul file system.

Ad un certo punto PEP 338 è in conflitto con PEP 328 :

... le importazioni relative si basano su __name__ per determinare la posizione del modulo corrente nella gerarchia dei pacchetti. In un modulo principale, il valore di __name__ è sempre '__main__' , quindi le importazioni relative esplicite falliranno sempre (poiché funzionano solo per un modulo all'interno di un pacchetto)

e per risolvere il problema, PEP 366 ha introdotto la variabile di livello superiore __package__:

Aggiungendo un nuovo attributo a livello di modulo, questo PEP consente alle importazioni relative di funzionare automaticamente se il modulo viene eseguito utilizzando l'opzione -m . Una piccola quantità di boilerplate nel modulo stesso consentirà alle relative importazioni di funzionare quando il file viene eseguito per nome. [...] Quando è presente [l'attributo], le importazioni relative saranno basate su questo attributo piuttosto che sull'attributo __name__ del modulo . [...] Quando il modulo principale è specificato dal suo nome file, l' attributo __package__ sarà impostato su Nessuno . [...] Quando il sistema di importazione rileva un'importazione relativa esplicita in un modulo senza __package__ impostato (o con esso impostato su Nessuno), calcolerà e memorizzerà il valore corretto (__name __. rpartition ('.') [0] per i moduli normali e __name__ per i moduli di inizializzazione del pacchetto)

(enfatizzare il mio)

Se __name__è '__main__', __name__.rpartition('.')[0]restituisce una stringa vuota. Ecco perché c'è una stringa vuota letterale nella descrizione dell'errore:

SystemError: Parent module '' not loaded, cannot perform relative import

La parte rilevante della PyImport_ImportModuleLevelObjectfunzione di CPython :

if (PyDict_GetItem(interp->modules, package) == NULL) {
    PyErr_Format(PyExc_SystemError,
            "Parent module %R not loaded, cannot perform relative "
            "import", package);
    goto error;
}

CPython solleva questa eccezione se non è stato in grado di trovare package(il nome del pacchetto) in interp->modules(accessibile come sys.modules). Poiché sys.modulesè "un dizionario che associa i nomi dei moduli ai moduli che sono già stati caricati" , è ora chiaro che il modulo padre deve essere importato in modo esplicito assoluto prima di eseguire l'importazione relativa .

Nota: la patch dal numero 18018 ha aggiunto un altro ifblocco , che verrà eseguito prima del codice sopra:

if (PyUnicode_CompareWithASCIIString(package, "") == 0) {
    PyErr_SetString(PyExc_ImportError,
            "attempted relative import with no known parent package");
    goto error;
} /* else if (PyDict_GetItem(interp->modules, package) == NULL) {
    ...
*/

Se package(come sopra) è una stringa vuota, il messaggio di errore sarà

ImportError: attempted relative import with no known parent package

Tuttavia, lo vedrai solo in Python 3.6 o versioni successive.

Soluzione n. 1: esegui lo script usando -m

Considera una directory (che è un pacchetto Python ):

.
├── package
│   ├── __init__.py
│   ├── module.py
│   └── standalone.py

Tutti i file nel pacchetto iniziano con le stesse 2 righe di codice:

from pathlib import Path
print('Running' if __name__ == '__main__' else 'Importing', Path(__file__).resolve())

Includo queste due righe solo per rendere evidente l'ordine delle operazioni. Possiamo ignorarli completamente, poiché non influiscono sull'esecuzione.

__init__.py e module.py contengono solo quelle due righe (cioè sono effettivamente vuote).

standalone.py tenta inoltre di importare module.py tramite l'importazione relativa:

from . import module  # explicit relative import

Sappiamo bene che /path/to/python/interpreter package/standalone.pyfallirà. Tuttavia, possiamo eseguire il modulo con l' -mopzione della riga di comando che "sys.path__main__ cercherà il modulo nominato ed eseguirà il suo contenuto come modulo" :

vaultah@base:~$ python3 -i -m package.standalone
Importing /home/vaultah/package/__init__.py
Running /home/vaultah/package/standalone.py
Importing /home/vaultah/package/module.py
>>> __file__
'/home/vaultah/package/standalone.py'
>>> __package__
'package'
>>> # The __package__ has been correctly set and module.py has been imported.
... # What's inside sys.modules?
... import sys
>>> sys.modules['__main__']
<module 'package.standalone' from '/home/vaultah/package/standalone.py'>
>>> sys.modules['package.module']
<module 'package.module' from '/home/vaultah/package/module.py'>
>>> sys.modules['package']
<module 'package' from '/home/vaultah/package/__init__.py'>

-mfa tutte le cose di importazione per te e le imposta automaticamente __package__, ma puoi farlo tu stesso in

Soluzione n. 2: impostare __package__ manualmente

Per favore trattalo come una prova di concetto piuttosto che una soluzione reale. Non è adatto per l'uso nel codice del mondo reale.

PEP 366 ha una soluzione alternativa a questo problema, tuttavia, è incompleto, poiché l'impostazione __package__da sola non è sufficiente. Dovrai importare almeno N pacchetti precedenti nella gerarchia dei moduli, dove N è il numero di directory principali (relative alla directory dello script) che verranno ricercate per il modulo da importare.

Così,

  1. Aggiungere la directory principale dell'ennesimo predecessore del modulo corrente asys.path

  2. Rimuovere la directory del file corrente da sys.path

  3. Importa il modulo padre del modulo corrente usando il suo nome completo

  4. Impostare __package__il nome completo da 2

  5. Eseguire l'importazione relativa

Prenderò in prestito i file dalla soluzione n. 1 e aggiungerò altri subpackages:

package
├── __init__.py
├── module.py
└── subpackage
    ├── __init__.py
    └── subsubpackage
        ├── __init__.py
        └── standalone.py

Questa volta standalone.py importerà module.py dal pacchetto del pacchetto usando la seguente importazione relativa

from ... import module  # N = 3

Dovremo precedere quella riga con il codice del boilerplate, per farlo funzionare.

import sys
from pathlib import Path

if __name__ == '__main__' and __package__ is None:
    file = Path(__file__).resolve()
    parent, top = file.parent, file.parents[3]

    sys.path.append(str(top))
    try:
        sys.path.remove(str(parent))
    except ValueError: # Already removed
        pass

    import package.subpackage.subsubpackage
    __package__ = 'package.subpackage.subsubpackage'

from ... import module # N = 3

Ci permette di eseguire standalone.py per nome file:

vaultah@base:~$ python3 package/subpackage/subsubpackage/standalone.py
Running /home/vaultah/package/subpackage/subsubpackage/standalone.py
Importing /home/vaultah/package/__init__.py
Importing /home/vaultah/package/subpackage/__init__.py
Importing /home/vaultah/package/subpackage/subsubpackage/__init__.py
Importing /home/vaultah/package/module.py

Una soluzione più generale racchiusa in una funzione è disponibile qui . Esempio di utilizzo:

if __name__ == '__main__' and __package__ is None:
    import_parents(level=3) # N = 3

from ... import module
from ...module.submodule import thing

Soluzione n. 3: utilizzare importazioni e strumenti di installazione assoluti

I passaggi sono -

  1. Sostituire le importazioni relative esplicite con importazioni assolute equivalenti

  2. Installa packageper renderlo improprio

Ad esempio, la struttura della directory può essere la seguente

.
├── project
│   ├── package
│   │   ├── __init__.py
│   │   ├── module.py
│   │   └── standalone.py
│   └── setup.py

dove setup.py è

from setuptools import setup, find_packages
setup(
    name = 'your_package_name',
    packages = find_packages(),
)

Il resto dei file è stato preso in prestito dalla soluzione n . 1 .

L'installazione ti permetterà di importare il pacchetto indipendentemente dalla tua directory di lavoro (supponendo che non ci saranno problemi di denominazione).

Possiamo modificare standalone.py per utilizzare questo vantaggio (passaggio 1):

from package import module  # absolute import

Modificare la directory di lavoro in projected eseguirla /path/to/python/interpreter setup.py install --user( --userinstalla il pacchetto nella directory dei pacchetti del sito ) (passaggio 2):

vaultah@base:~$ cd project
vaultah@base:~/project$ python3 setup.py install --user

Verifichiamo che ora è possibile eseguire standalone.py come script:

vaultah@base:~/project$ python3 -i package/standalone.py
Running /home/vaultah/project/package/standalone.py
Importing /home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/__init__.py
Importing /home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/module.py
>>> module
<module 'package.module' from '/home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/module.py'>
>>> import sys
>>> sys.modules['package']
<module 'package' from '/home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/__init__.py'>
>>> sys.modules['package.module']
<module 'package.module' from '/home/vaultah/.local/lib/python3.6/site-packages/your_package_name-0.0.0-py3.6.egg/package/module.py'>

Nota : se decidi di seguire questa strada, ti conviene usare ambienti virtuali per installare i pacchetti in modo isolato.

Soluzione n. 4: utilizzare le importazioni assolute e un po 'di codice del boilerplate

Francamente, l'installazione non è necessaria: potresti aggiungere un po 'di codice boilerplate allo script per far funzionare le importazioni assolute.

Prenderò in prestito file dalla soluzione n. 1 e cambierò standalone.py :

  1. Aggiungi la directory principale del pacchetto a sys.path prima di tentare di importare qualsiasi cosa dal pacchetto usando le importazioni assolute:

    import sys
    from pathlib import Path # if you haven't already done so
    file = Path(__file__).resolve()
    parent, root = file.parent, file.parents[1]
    sys.path.append(str(root))
    
    # Additionally remove the current file's directory from sys.path
    try:
        sys.path.remove(str(parent))
    except ValueError: # Already removed
        pass
  2. Sostituisci l'importazione relativa con l'importazione assoluta:

    from package import module  # absolute import

standalone.py funziona senza problemi:

vaultah@base:~$ python3 -i package/standalone.py
Running /home/vaultah/package/standalone.py
Importing /home/vaultah/package/__init__.py
Importing /home/vaultah/package/module.py
>>> module
<module 'package.module' from '/home/vaultah/package/module.py'>
>>> import sys
>>> sys.modules['package']
<module 'package' from '/home/vaultah/package/__init__.py'>
>>> sys.modules['package.module']
<module 'package.module' from '/home/vaultah/package/module.py'>

Sento che dovrei avvertirti: cerca di non farlo, specialmente se il tuo progetto ha una struttura complessa.


Come nota a margine , PEP 8 raccomanda l'uso di importazioni assolute, ma afferma che in alcuni scenari sono accettabili esplicite importazioni relative:

Si consigliano importazioni assolute, in quanto di solito sono più leggibili e tendono a comportarsi meglio (o almeno a fornire messaggi di errore migliori). [...] Tuttavia, le importazioni relative esplicite sono un'alternativa accettabile alle importazioni assolute, soprattutto quando si tratta di layout di pacchetti complessi in cui l'uso di importazioni assolute sarebbe inutilmente prolisso.


3
È possibile impostare __package__manualmente se il nome è __main__per risolvere il problema?
Paulo Scardine,

Grazie, belle risposte! Sono stato in grado di caricare il modulo utilizzando il impmodulo e impostato di __package__conseguenza, ma il risultato è chiaramente un anti-pattern.
Paulo Scardine,

Ottengo l'errore AttributeError: 'PosixPath' object has no attribute 'path'.
utente

Grazie per la rapida risposta Sto usando il pacchetto nltk, ricevo un errore: `File" /usr/local/lib/python3.5/dist-packages/nltk/__init__.py ", riga 115, in <module> da nltk.decorators import decorator, memoize File "/usr/local/lib/python3.5/dist-packages/nltk/decorators.py", riga 23, in <module> sys.path = [p per p in sys.path if "nltk "not in p] File" /usr/local/lib/python3.5/dist-packages/nltk/decorators.py ", riga 23, in <listcomp> sys.path = [p per p in sys.path if" nltk "not in p] TypeError: l'argomento di tipo 'PosixPath' non è iterabile`
utente

1
Puoi anche importare un file in base al percorso del file (anche relativo): docs.python.org/3/library/…
Ctrl-C

86

Inseriscilo nel file __init__.py del pacchetto :

# For relative imports to work in Python 3.6
import os, sys; sys.path.append(os.path.dirname(os.path.realpath(__file__)))

Supponendo che il tuo pacchetto sia così:

├── project
   ├── package
      ├── __init__.py
      ├── module1.py
      └── module2.py
   └── setup.py

Ora usa le importazioni regolari nel tuo pacchetto, come:

# in module2.py
from module1 import class1

Funziona sia con Python 2 che 3.


1
funziona se lo impacchettiamo come weel
Alex Punnen,

1
Penso anche che questo meriti più voti. Mettendo questo in ogni __init__.pyrisolverai sostanzialmente tutti i relativi errori di importazione.
frankliuao,

3
Non posso parlare per gli altri, ma tendo ad evitare di modificarlo sys.pathperché sono preoccupato che possa influire su altri codici. (In parte questo è perché non conosco la complessità di come funziona.)
pianoJames

@pianoJames So cosa intendi, questa correzione magica (apparentemente, dopo un sacco di problemi) sembra un po 'troppo facile. Ma funziona Sarebbe interessato non sapere da quelli che sanno se questo ha effetti collaterali negativi.
Jon,

Lo sto usando ora: e finora tutto bene.
javadba,

37

Ho riscontrato questo problema. Una soluzione alternativa per l'hacking viene importata tramite un blocco if / else come segue:

#!/usr/bin/env python3
#myothermodule

if __name__ == '__main__':
    from mymodule import as_int
else:
    from .mymodule import as_int


# Exported function
def add(a, b):
    return as_int(a) + as_int(b)

# Test function for module  
def _test():
    assert add('1', '1') == 2

if __name__ == '__main__':
    _test()

29
non è una soluzione molto bella. inoltre, nudo except:è male. usa except ImportError:invece!
ThiefMaster

6
È SystemErrorqui. (Py 3.4)
Avi

8
Questa non è un'idea terribile, ma sarebbe meglio rilevare quale importazione usare piuttosto che provare / tranne. Qualcosa del genere if __name__ == '__main__': from mymod import as_int; else: from .mymod import as_int.
Perkins,

@Perkins Beh ... nella maggior parte dei casi non lo sarebbe . Penso che le importazioni relative possano essere l'eccezione però.
wizzwizz4,

8

Spero che questo abbia valore per qualcuno là fuori - ho esaminato una mezza dozzina di post stackoverflow cercando di capire le importazioni relative simili a ciò che è stato pubblicato qui sopra. Ho impostato tutto come suggerito, ma stavo ancora colpendoModuleNotFoundError: No module named 'my_module_name'

Da quando stavo solo sviluppando localmente e giocando, non avevo creato / eseguito un setup.pyfile. Apparentemente non avevo nemmeno impostato il mio PYTHONPATH.

Mi sono reso conto che quando ho eseguito il mio codice come quando i test erano nella stessa directory del modulo, non sono riuscito a trovare il mio modulo:

$ python3 test/my_module/module_test.py                                                                                                               2.4.0
Traceback (most recent call last):
  File "test/my_module/module_test.py", line 6, in <module>
    from my_module.module import *
ModuleNotFoundError: No module named 'my_module'

Tuttavia, quando ho specificato esplicitamente il percorso le cose hanno iniziato a funzionare:

$ PYTHONPATH=. python3 test/my_module/module_test.py                                                                                                  2.4.0
...........
----------------------------------------------------------------------
Ran 11 tests in 0.001s

OK

Quindi, nel caso in cui qualcuno abbia provato alcuni suggerimenti, crede che il suo codice sia strutturato correttamente e si trovi ancora in una situazione simile a me stesso provo una delle seguenti soluzioni se non esporti la directory corrente nel tuo PYTHONPATH:

  1. Esegui il codice e includi esplicitamente il percorso in questo modo: $ PYTHONPATH=. python3 test/my_module/module_test.py
  2. Per evitare di chiamare PYTHONPATH=., creare un setup.pyfile con contenuti come i seguenti ed eseguire python setup.py developmentper aggiungere pacchetti al percorso:
# setup.py
from setuptools import setup, find_packages

setup(
    name='sample',
    packages=find_packages()
)

6

Ho dovuto eseguire python3 dalla directory principale del progetto per farlo funzionare.

Ad esempio, se il progetto ha la seguente struttura:

project_demo/
├── main.py
├── some_package/
   ├── __init__.py
   └── project_configs.py
└── test/
    └── test_project_configs.py

Soluzione

Vorrei eseguire python3 nella cartella project_demo / e quindi eseguire un

from some_package import project_configs

4

Per ovviare a questo problema, ho escogitato una soluzione con il pacchetto di riconfezionamento , che ha funzionato per me per un po 'di tempo. Aggiunge la directory superiore al percorso lib:

import repackage
repackage.up()
from mypackage.mymodule import myfunction

Il reimballaggio può effettuare importazioni relative che funzionano in una vasta gamma di casi, utilizzando una strategia intelligente (ispezione dello stack di chiamate).


Di gran lunga la soluzione più semplice! Grazie!
CodingInCircles

1
Grazie! Invece di provare a dare la risposta migliore, ho cercato di dare una risposta utilizzabile :-)
fralau

3

se entrambi i pacchetti si trovano nel percorso di importazione (sys.path) e il modulo / classe desiderato è in example / example.py, quindi per accedere alla classe senza importazione relativa provare:

from example.example import fkt

1

Penso che la soluzione migliore sia creare un pacchetto per il tuo modulo: qui maggiori informazioni su come farlo.

Una volta che hai un pacchetto di cui non devi preoccuparti per l'importazione relativa, puoi semplicemente fare importazioni assolute.


0

Avevo un problema simile: avevo bisogno di un servizio Linux e di un plugin cgi che usassero costanti comuni per cooperare. Il modo 'naturale' per farlo è quello di inserirli nel file .py di inizializzazione del pacchetto, ma non riesco ad avviare il plugin cgi con il parametro -m.

La mia soluzione finale era simile alla soluzione n. 2 sopra:

import sys
import pathlib as p
import importlib

pp = p.Path(sys.argv[0])
pack = pp.resolve().parent

pkg = importlib.import_module('__init__', package=str(pack))

Lo svantaggio è che devi aggiungere il prefisso alle costanti (o funzioni comuni) con pkg:

print(pkg.Glob)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.