Usa 'import module' o 'from module import'?


411

Ho provato a trovare una guida completa sull'opportunità di utilizzare import moduleo from module import? Ho appena iniziato con Python e sto cercando di iniziare pensando alle migliori pratiche.

In sostanza, speravo se qualcuno potrebbe condividere le loro esperienze, quali preferenze altri sviluppatori hanno e qual è il modo migliore per evitare eventuali trucchi lungo la strada?


5
Volevo solo farti sapere che la risposta selezionata è sbagliata. Afferma che la differenza è soggettiva mentre c'è una differenza. Ciò potrebbe portare a errori difficili da rilevare. Vedi la risposta di Michael Ray Lovetts.
Mayou36,


2
C'è un inferno di una differenza tra l'importazione di specifici chiamati identificatori 'from module import X,Y,Zvs'from module import * . Quest'ultimo inquina il tuo spazio dei nomi e può dare risultati imprevedibili a seconda di cosa sta succedendo nel modulo. Peggio ancora sta facendo from module import *con più moduli.
smci,

Risposte:


474

La differenza tra import modulee from module import fooè principalmente soggettiva. Scegli quello che ti piace di più e sii coerente nel tuo utilizzo. Ecco alcuni punti per aiutarti a decidere.

import module

  • Professionisti:
    • Meno mantenimento delle tue importdichiarazioni. Non è necessario aggiungere ulteriori importazioni per iniziare a utilizzare un altro elemento dal modulo
  • Contro:
    • Digitare module.fooil codice può essere noioso e ridondante (il tedio può essere ridotto al minimo utilizzando import module as moquindi la digitazione mo.foo)

from module import foo

  • Professionisti:
    • Meno battitura da usare foo
    • Maggiore controllo su quali elementi di un modulo sono accessibili
  • Contro:
    • Per utilizzare un nuovo elemento dal modulo devi aggiornare la tua importdichiarazione
    • Perdi contesto foo. Ad esempio, è meno chiaro cosa ceil()fa rispetto amath.ceil()

Entrambi i metodi sono accettabili, ma non usare from module import *.

Per qualsiasi ragionevole set di codice di grandi dimensioni, se import *probabilmente lo si sta cementando nel modulo, non sarà possibile rimuoverlo. Questo perché è difficile determinare quali elementi utilizzati nel codice provengono da 'module', rendendo facile arrivare al punto in cui si pensa di non utilizzare importpiù, ma è estremamente difficile esserne sicuri.


66
+1 per scoraggiare l'utilizzo di "from module import *", ingombra semplicemente lo spazio dei nomi.
Christian Witts,

22
ingombrare lo spazio dei nomi non è la parte più problematica di "import *", è la riduzione della leggibilità: qualsiasi conflitto di nomi si mostrerà nei test (unit). Ma tutti i nomi che usi dal modulo importato saranno nudi, con nessun suggerimento da dove provengano. Detesto assolutamente "import *".
Jürgen A. Erhard,

21
Lo Zen di Python non dice esplicito che è meglio di implicito?
Antony Koch,

8
from module import *può essere particolarmente utile, se si utilizza come: if(windows):\n\t from module_win import * \n else: \n\t from module_lin import *. Quindi il tuo modulo genitore può potenzialmente contenere nomi di funzioni indipendenti dal sistema operativo, se i nomi di funzione in module_lin e module_win hanno gli stessi nomi. È come ereditare in modo condizionale entrambe le classi.
anishsane,

19
@anishsane. C'è un altro modo per farlo. import module_win come qualcosa. Quindi usa sempre qualcosa.method_name ()
Vinay

163

C'è un altro dettaglio qui, non menzionato, relativo alla scrittura su un modulo. Certo, potrebbe non essere molto comune, ma di tanto in tanto ne ho bisogno.

A causa del modo in cui i riferimenti e l'associazione dei nomi funzionano in Python, se si desidera aggiornare alcuni simboli in un modulo, ad esempio foo.bar, dall'esterno di quel modulo e avere un altro codice di importazione "vedi" che cambia, è necessario importare un certo modo. Per esempio:

modulo foo:

bar = "apples"

modulo a:

import foo
foo.bar = "oranges"   # update bar inside foo module object

modulo b:

import foo           
print foo.bar        # if executed after a's "foo.bar" assignment, will print "oranges"

Tuttavia, se si importano nomi di simboli anziché nomi di moduli, questo non funzionerà.

Ad esempio, se lo faccio nel modulo a:

from foo import bar
bar = "oranges"

Nessun codice al di fuori di a vedrà la barra come "arance" perché la mia impostazione della barra ha semplicemente influenzato il nome "bar" all'interno del modulo a, non ha "raggiunto" l'oggetto modulo foo e ha aggiornato la sua "barra".


Con quell'ultimo esempio, puoi ancora chiamare 'foo.bar = "orange"' per aggiornare 'bar' all'interno di 'foo'?
velocirabbit,

4
No, nell'ultimo esempio, il nome 'foo' è sconosciuto
Ghislain Leveque,

31
QUESTA risposta fornisce la "vera" risposta alla domanda: qual è la differenza tra le due varianti di importazione
Mayou36

3
Ha scritto uno snippet per dimostrare che questa risposta è assolutamente giusta, ma qual è la logica alla base di questo?
Huangbeidu,

Penso che quello che stai dicendo sia importare i nomi dei simboli per avere variabili locali ma importare i nomi dei moduli per avere variabili globali ???
WinEunuuchs2Unix il

79

Anche se molte persone hanno già spiegato riguardo al importvs import from, voglio provare a spiegare un po 'di più su cosa succede sotto il cofano e dove si trovano tutti i luoghi in cui cambia.


import foo:

Importa fooe crea un riferimento a quel modulo nello spazio dei nomi corrente. Quindi è necessario definire il percorso del modulo completo per accedere a un particolare attributo o metodo dall'interno del modulo.

Ad esempio foo.barma nobar

from foo import bar:

Importa fooe crea riferimenti a tutti i membri elencati ( bar). Non imposta la variabile foo.

Ad esempio barma no bazofoo.baz

from foo import *:

Importa fooe crea riferimenti a tutti gli oggetti pubblici definiti da quel modulo nello spazio dei nomi corrente (tutto ciò che è elencato __all__se __all__esiste, altrimenti tutto ciò che non inizia con _). Non imposta la variabile foo.

Ad esempio, bare bazma non _quxo foo._qux.


Ora vediamo quando lo facciamo import X.Y:

>>> import sys
>>> import os.path

Verifica sys.modulescon nome ose os.path:

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

Controlla globals()e locals()dice lo spazio dei nomi con ose os.path:

 >>> globals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> locals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> globals()['os.path']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os.path'
>>>

Dall'esempio sopra abbiamo scoperto che solo osè inserito nello spazio dei nomi locale e globale. Quindi, dovremmo essere in grado di usare:

 >>> os
 <module 'os' from
  '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
 >>> os.path
 <module 'posixpath' from
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
 >>>

Ma non path.

>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

Una volta eliminato lo osspazio dei nomi from local (), non sarà possibile accedervi os, os.pathanche se esistono in sys.modules:

>>> del locals()['os']
>>> os
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

Ora parliamo di import from:

from:

>>> import sys
>>> from os import path

Verifica sys.modulescon ose os.path:

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

Abbiamo scoperto che in sys.modulesabbiamo trovato lo stesso di prima usandoimport name

OK, controlliamo come appare in locals()e globals()spazio dei nomi:

>>> globals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> locals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['os']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os'
>>>

È possibile accedere utilizzando il nome pathnon tramite os.path:

>>> path
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

Eliminiamo 'percorso' da locals():

>>> del locals()['path']
>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

Un ultimo esempio usando un alias:

>>> from os import path as HELL_BOY
>>> locals()['HELL_BOY']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['HELL_BOY']
<module 'posixpath' from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>

E nessun percorso definito:

>>> globals()['path']
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 'path'
>>>

8
Mentre questo è dettagliato, questa è davvero la migliore risposta nell'elenco per una domanda abbastanza complessa. Fornisce un codice reale per aiutare a spiegare le sottigliezze "nascoste", che sono più importanti dello stile, per questo particolare problema. Vorrei poterlo votare più di una volta!
Mike Williamson,

L'uso as SYMBOLcambia come funziona questa risposta?
Maximilian Burszley,

40

Entrambi i modi sono supportati per un motivo: ci sono momenti in cui uno è più appropriato dell'altro.

  • import module: bello quando stai usando molti bit dal modulo. lo svantaggio è che dovrai qualificare ogni riferimento con il nome del modulo.

  • from module import ...: bello che gli articoli importati siano utilizzabili direttamente senza il prefisso del nome del modulo. Lo svantaggio è che devi elencare ogni cosa che usi e che non è chiaro nel codice da dove provenga qualcosa.

Quale usare dipende da quale rende il codice chiaro e leggibile, e ha più che a che fare con le preferenze personali. Mi rivolgo import modulegeneralmente perché nel codice è molto chiaro da dove provenga un oggetto o una funzione. Io uso from module import ...quando sto usando un oggetto / funzione un sacco nel codice.


1
C'è un modo di usare from M import Xe ottenere comunque il vantaggio di utilizzare i qualificatori in qualche modo? Sembra che potresti ottenere il meglio da entrambi i mondi se ancora M.Xdopo l'importazione.
artropodi,

@artgropod: Kinda. Si può fare class m: from something.too.long import x, y, z. Non lo consiglierei davvero però.
Sdraiati Ryan l'

35

Personalmente uso sempre

from package.subpackage.subsubpackage import module

e quindi accedere a tutto come

module.function
module.modulevar

ecc. La ragione è che allo stesso tempo hai una breve invocazione e definisci chiaramente lo spazio dei nomi dei moduli di ogni routine, qualcosa di molto utile se devi cercare l'uso di un determinato modulo nella tua fonte.

Inutile dire che non usare l'importazione *, perché inquina il tuo spazio dei nomi e non ti dice da dove proviene una data funzione (da quale modulo)

Naturalmente, puoi avere problemi se hai lo stesso nome di modulo per due moduli diversi in due pacchetti diversi, come

from package1.subpackage import module
from package2.subpackage import module

in questo caso, ovviamente, si verificano problemi, ma poi c'è un forte suggerimento che il layout del pacchetto è difettoso e si deve ripensare.


10
Nell'ultimo caso, puoi sempre usare: import pkgN.sub.module come modN che ti dà nomi distinti per ciascun modulo. È inoltre possibile utilizzare il modello 'import modulename as mod1' per abbreviare un nome lungo o per passare da un'implementazione della stessa API (ad esempio moduli API DB) a un singolo cambio di nome.
Jeff Shannon,

15
import module

È il migliore quando utilizzerai molte funzioni del modulo.

from module import function

È preferibile quando si desidera evitare di inquinare lo spazio dei nomi globale con tutte le funzioni e i tipi di un modulo solo quando è necessario function.


7
Sicuramente l'unica cosa nello spazio dei nomi globale se si fa 'import module' è 'module'? Inquini lo spazio dei nomi solo se fai "da ... import *".
John Fouhy,

10

Ho appena scoperto un'altra sottile differenza tra questi due metodi.

Se il modulo fooutilizza una seguente importazione:

from itertools import count

Quindi il modulo barpuò usare per errore countcome se fosse stato definito in foo, non in itertools:

import foo
foo.count()

Se fooutilizza:

import itertools

l'errore è ancora possibile, ma è meno probabile che venga commesso. bardeve:

import foo
foo.itertools.count()

Questo mi ha causato qualche problema. Avevo un modulo che per errore importava un'eccezione da un modulo che non lo definiva, lo importava solo da un altro modulo (usando from module import SomeException). Quando l'importazione non era più necessaria e rimossa, il modulo offensivo era rotto.


10

Ecco un'altra differenza non menzionata. Questo è copiato letteralmente da http://docs.python.org/2/tutorial/modules.html

Si noti che quando si utilizza

from package import item

l'articolo può essere un sottomodulo (o un sotto-pacchetto) del pacchetto, o qualche altro nome definito nel pacchetto, come una funzione, classe o variabile. La dichiarazione di importazione verifica innanzitutto se l'articolo è definito nel pacchetto; in caso contrario, presuppone che sia un modulo e tenta di caricarlo. Se non riesce a trovarlo, viene sollevata un'eccezione ImportError.

Al contrario, quando si utilizza la sintassi come

import item.subitem.subsubitem

ogni articolo tranne l'ultimo deve essere un pacchetto; l'ultimo elemento può essere un modulo o un pacchetto ma non può essere una classe o una funzione o una variabile definita nell'elemento precedente.


Un'altra cosa che ho notato è che se l'articolo è anche un sottomodulo all'interno del pacchetto, allora "dall'importazione del pacchetto" funziona ma "importa pacchetto" package.item.subitem = ... non funziona con un init .py vuoto del pacchetto, a meno che non avere "import item" nel file file init del pacchetto.
Amitoz Dandiana,

6

Dato che sono anche un principiante, cercherò di spiegarlo in modo semplice: in Python, abbiamo tre tipi di importaffermazioni che sono:

1. Importazioni generiche:

import math

questo tipo di importazione è il mio preferito personale, l'unico aspetto negativo di questa tecnica di importazione è che se è necessario utilizzare qualsiasi funzione del modulo è necessario utilizzare la sintassi seguente:

math.sqrt(4)

ovviamente, aumenta lo sforzo di digitazione, ma come principiante, ti aiuterà a tenere traccia del modulo e della funzione ad esso associati (un buon editor di testo ridurrà significativamente lo sforzo di digitazione ed è raccomandato).

Lo sforzo di battitura può essere ulteriormente ridotto usando questa dichiarazione di importazione:

import math as m

ora, invece di usare math.sqrt()puoi usare m.sqrt().

2. Importazioni di funzioni:

from math import sqrt

questo tipo di importazione è più adatto se il tuo codice deve solo accedere a singole o poche funzioni dal modulo, ma per utilizzare qualsiasi nuovo elemento dal modulo devi aggiornare la dichiarazione di importazione.

3. Importazioni universali:

from math import * 

Sebbene riduca significativamente lo sforzo di digitazione, ma non è raccomandato perché riempirà il codice con varie funzioni del modulo e il loro nome potrebbe essere in conflitto con il nome delle funzioni definite dall'utente. esempio:

Se hai una funzione del tuo proprio sqrt e importi la matematica, la tua funzione è sicura: c'è il tuo sqrt e c'è math.sqrt. Se lo fai dall'importazione matematica *, tuttavia, hai un problema: vale a dire, due diverse funzioni con lo stesso nome esatto. Fonte: Codecademy


5
import package
import module

Con import, il token deve essere un modulo (un file contenente i comandi Python) o un pacchetto (una cartella che sys.pathcontiene un file __init__.py).

Quando sono presenti pacchetti secondari:

import package1.package2.package
import package1.package2.module

i requisiti per cartella (pacchetto) o file (modulo) sono gli stessi, ma la cartella o il file deve essere all'interno package2che deve essere all'interno package1, ed entrambi package1e package2devono contenere __init__.pyfile. https://docs.python.org/2/tutorial/modules.html

Con lo fromstile di importazione:

from package1.package2 import package
from package1.package2 import module

il pacchetto o il modulo inserisce lo spazio dei nomi del file contenente l' importistruzione come module(o package) anziché package1.package2.module. Puoi sempre associare un nome più conveniente:

a = big_package_name.subpackage.even_longer_subpackage_name.function

Solo lo fromstile di importazione ti consente di nominare una particolare funzione o variabile:

from package3.module import some_function

è permesso, ma

import package3.module.some_function 

non è permesso.


4

In aggiunta a ciò che la gente ha detto from x import *: oltre a rendere più difficile dire da dove provengono i nomi, questo getta via checker di codice come Pylint. Riporteranno quei nomi come variabili indefinite.


3

La mia risposta a questa dipende principalmente dal primo, da quanti moduli diversi userò. Se ne userò solo uno o due, lo userò spesso from... importdato che riduce il numero di tasti nel resto del file, ma se userò molti moduli diversi, preferisco soloimport perché ciò significa che ogni riferimento al modulo è auto-documentato. Riesco a vedere da dove viene ogni simbolo senza dover dare la caccia.

Di solito preferisco lo stile di auto-documentazione dell'importazione semplice e cambio da a ... import quando il numero di volte in cui devo digitare il nome del modulo aumenta da 10 a 20, anche se c'è un solo modulo da importare.


1

Una delle differenze significative che ho scoperto di cui nessuno ha parlato sorprendentemente è che usando la semplice importazione è possibile accedere private variablee private functionsdal modulo importato, cosa impossibile con la dichiarazione from-import .

inserisci qui la descrizione dell'immagine

Codice nell'immagine:

setting.py

public_variable = 42
_private_variable = 141
def public_function():
    print("I'm a public function! yay!")
def _private_function():
    print("Ain't nobody accessing me from another module...usually")

plain_importer.py

import settings
print (settings._private_variable)
print (settings.public_variable)
settings.public_function()
settings._private_function()

# Prints:
# 141
# 42
# I'm a public function! yay!
# Ain't nobody accessing me from another module...usually

from_importer.py

from settings import *
#print (_private_variable) #doesn't work
print (public_variable)
public_function()
#_private_function()   #doesn't work

0

Modulo di importazione: non sono necessari ulteriori sforzi per recuperare un'altra cosa dal modulo. Ha svantaggi come la digitazione ridondante

Importazione modulo da: meno digitazione e maggiore controllo su quali elementi di un modulo sono accessibili. Per utilizzare un nuovo elemento dal modulo è necessario aggiornare la dichiarazione di importazione.


0

Ci sono alcuni moduli integrati che contengono principalmente funzioni nude ( base64 , math , os , shutil , sys , time , ...) ed è sicuramente una buona pratica avere queste funzioni nude legate ad alcuni spazi dei nomi e quindi migliorare la leggibilità del tuo codice. Considera quanto è più difficile comprendere il significato di queste funzioni senza il loro spazio dei nomi:

copysign(foo, bar)
monotonic()
copystat(foo, bar)

rispetto a quando sono associati ad alcuni moduli:

math.copysign(foo, bar)
time.monotonic()
shutil.copystat(foo, bar)

A volte è persino necessario lo spazio dei nomi per evitare conflitti tra i diversi moduli ( json.load vs. pickle.load )


D'altra parte ci sono alcuni moduli che contengono principalmente classi ( configparser , datetime , tempfile , zipfile , ...) e molti di essi rendono i loro nomi di classe abbastanza autoesplicativi:

configparser.RawConfigParser()
datetime.DateTime()
email.message.EmailMessage()
tempfile.NamedTemporaryFile()
zipfile.ZipFile()

quindi si può discutere se l'utilizzo di queste classi con lo spazio dei nomi del modulo aggiuntivo nel codice aggiunge alcune nuove informazioni o semplicemente allunga il codice.


0

Vorrei aggiungere a questo, ci sono alcune cose da considerare durante le chiamate di importazione:

Ho la seguente struttura:

mod/
    __init__.py
    main.py
    a.py
    b.py
    c.py
    d.py

main.py:

import mod.a
import mod.b as b
from mod import c
import d

dis.dis mostra la differenza:

  1           0 LOAD_CONST               0 (-1)
              3 LOAD_CONST               1 (None)
              6 IMPORT_NAME              0 (mod.a)
              9 STORE_NAME               1 (mod)

  2          12 LOAD_CONST               0 (-1)
             15 LOAD_CONST               1 (None)
             18 IMPORT_NAME              2 (b)
             21 STORE_NAME               2 (b)

  3          24 LOAD_CONST               0 (-1)
             27 LOAD_CONST               2 (('c',))
             30 IMPORT_NAME              1 (mod)
             33 IMPORT_FROM              3 (c)
             36 STORE_NAME               3 (c)
             39 POP_TOP

  4          40 LOAD_CONST               0 (-1)
             43 LOAD_CONST               1 (None)
             46 IMPORT_NAME              4 (mod.d)
             49 LOAD_ATTR                5 (d)
             52 STORE_NAME               5 (d)
             55 LOAD_CONST               1 (None)

Alla fine sembrano uguali (STORE_NAME è il risultato in ogni esempio), ma vale la pena notare se è necessario considerare le seguenti quattro importazioni circolari:

Esempio 1

foo/
   __init__.py
   a.py
   b.py
a.py:
import foo.b 
b.py:
import foo.a
>>> import foo.a
>>>

Questo funziona

example2

bar/
   __init__.py
   a.py
   b.py
a.py:
import bar.b as b
b.py:
import bar.a as a
>>> import bar.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "bar\a.py", line 1, in <module>
    import bar.b as b
  File "bar\b.py", line 1, in <module>
    import bar.a as a
AttributeError: 'module' object has no attribute 'a'

Niente da fare

Example3

baz/
   __init__.py
   a.py
   b.py
a.py:
from baz import b
b.py:
from baz import a
>>> import baz.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "baz\a.py", line 1, in <module>
    from baz import b
  File "baz\b.py", line 1, in <module>
    from baz import a
ImportError: cannot import name a

Problema simile ... ma chiaramente da x import y non è lo stesso di import import xy di y

Esempio4

qux/
   __init__.py
   a.py
   b.py
a.py:
import b 
b.py:
import a
>>> import qux.a
>>>

Anche questo funziona


0

Questa è la mia struttura di directory della mia directory corrente:

.  
└─a  
   └─b  
     └─c
  1. L' importistruzione ricorda tutti i nomi intermedi .
    Questi nomi devono essere qualificati:

    In[1]: import a.b.c
    
    In[2]: a
    Out[2]: <module 'a' (namespace)>
    
    In[3]: a.b
    Out[3]: <module 'a.b' (namespace)>
    
    In[4]: a.b.c
    Out[4]: <module 'a.b.c' (namespace)>
  2. L' from ... import ...istruzione ricorda solo il nome importato .
    Questo nome non deve essere qualificato:

    In[1]: from a.b import c
    
    In[2]: a
    NameError: name 'a' is not defined
    
    In[2]: a.b
    NameError: name 'a' is not defined
    
    In[3]: a.b.c
    NameError: name 'a' is not defined
    
    In[4]: c
    Out[4]: <module 'a.b.c' (namespace)>

  • Nota: ovviamente, ho riavviato la mia console Python tra i passaggi 1 e 2.

0

Come menziona Jan Wrobel , un aspetto delle diverse importazioni è il modo in cui le importazioni vengono divulgate.

Modulo mymath

from math import gcd
...

Uso di mymath :

import mymath
mymath.gcd(30, 42)  # will work though maybe not expected

Se ho importato gcdsolo per uso interno, non divulgarlo agli utenti dimymath , questo può essere scomodo. Ho questo abbastanza spesso, e nella maggior parte dei casi voglio "mantenere i miei moduli puliti".

A parte la proposta di Jan Wrobel di oscurare un po 'di più utilizzando import mathinvece, ho iniziato a nascondere le importazioni dalla divulgazione utilizzando un carattere di sottolineatura principale:

# for instance...
from math import gcd as _gcd
# or...
import math as _math

Nei progetti più grandi questa "best practice" mi consente di controllare esattamente ciò che viene rivelato alle importazioni successive e ciò che non lo è. Ciò mantiene i miei moduli puliti e ripaga a una determinata dimensione del progetto.

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.