Gunakan 'modul impor' atau 'dari modul impor'?

411

Saya sudah mencoba menemukan panduan komprehensif tentang apakah yang terbaik untuk digunakan import moduleatau from module import? Saya baru saja mulai dengan Python dan saya mencoba memulai dengan praktik terbaik dalam pikiran.

Pada dasarnya, saya berharap jika ada yang bisa berbagi pengalaman mereka, preferensi apa yang dimiliki pengembang lain dan apa cara terbaik untuk menghindari gotcha di jalan?

Filip Dupanović
sumber
5
Saya hanya ingin memberi tahu Anda, bahwa jawaban yang dipilih salah. Ini menyatakan bahwa perbedaan itu subyektif sedangkan ada perbedaan. Ini dapat menyebabkan sulitnya mendeteksi bug. Lihat jawaban Michael Ray Lovetts.
Mayou36
2
Ada neraka perbedaan antara mengimpor tertentu bernama pengidentifikasi 'from module import X,Y,Zvs'from module import * . Yang terakhir mencemari namespace Anda dan dapat memberikan hasil yang tidak terduga tergantung pada apa yang terjadi di modul. Lebih buruk lagi masih melakukan from module import *dengan beberapa modul.
smci

Jawaban:

474

Perbedaan antara import moduledan from module import footerutama subyektif. Pilih yang paling Anda sukai dan konsisten dalam menggunakannya. Berikut adalah beberapa poin untuk membantu Anda memutuskan.

import module

  • Pro:
    • Kurang pemeliharaan importlaporan Anda . Tidak perlu menambahkan impor tambahan untuk mulai menggunakan item lain dari modul
  • Cons:
    • Mengetik module.fookode Anda bisa membosankan dan berlebihan (kebosanan dapat diminimalkan dengan menggunakan import module as molalu mengetik mo.foo)

from module import foo

  • Pro:
    • Kurang mengetik untuk digunakan foo
    • Lebih banyak kontrol atas item modul mana yang dapat diakses
  • Cons:
    • Untuk menggunakan item baru dari modul, Anda harus memperbarui importpernyataan Anda
    • Anda kehilangan konteks tentang foo. Misalnya, kurang jelas apa yang ceil()dibandingkan denganmath.ceil()

Metode mana pun dapat diterima, tetapi jangan gunakan from module import *.

Untuk sejumlah besar kode yang masuk akal, jika Anda import *kemungkinan akan memasukkannya ke dalam modul, tidak dapat dihapus. Ini karena sulit untuk menentukan item apa yang digunakan dalam kode berasal dari 'modul', membuatnya mudah untuk sampai ke titik di mana Anda pikir Anda tidak menggunakan importlagi tetapi sangat sulit untuk memastikan.

Mark Roddy
sumber
66
+1 untuk mencegah penggunaan "dari impor modul *", ini hanya mengacaukan namespace.
Christian Witts
22
mengacaukan namespace bukan bagian yang paling bermasalah dari "impor *", ini adalah pengurangan dalam keterbacaan: Setiap konflik nama akan muncul dalam pengujian (unit). Tetapi semua nama yang Anda gunakan dari modul yang diimpor akan kosong, dengan sedikit petunjuk apakah itu berasal. Saya benar-benar benci "impor *".
Jürgen A. Erhard
21
Bukankah Zen dari Python mengatakan eksplisit lebih baik daripada implisit?
Antony Koch
8
from module import *dapat sangat berguna, jika menggunakannya sebagai: if(windows):\n\t from module_win import * \n else: \n\t from module_lin import *. Maka modul induk Anda berpotensi berisi nama fungsi independen OS, jika nama fungsi di module_lin & module_win memiliki nama yang sama. Ini seperti mewarisi kedua kelas secara bersyarat.
anishsane
19
@anishsane. Ada cara lain melakukannya. import module_win sebagai sesuatu. Maka selalu gunakan something.method_name ()
Vinay
163

Ada detail lain di sini, tidak disebutkan, terkait dengan menulis ke modul. Memang ini mungkin tidak terlalu umum, tetapi saya membutuhkannya dari waktu ke waktu.

Karena cara referensi dan pengikatan nama berfungsi dalam Python, jika Anda ingin memperbarui beberapa simbol dalam sebuah modul, katakan foo.bar, dari luar modul itu, dan minta kode impor lainnya "lihat" perubahan itu, Anda harus mengimpor foo a cara tertentu. Sebagai contoh:

modul foo:

bar = "apples"

modul a:

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

modul b:

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

Namun, jika Anda mengimpor nama simbol alih-alih nama modul, ini tidak akan berfungsi.

Sebagai contoh, jika saya melakukan ini dalam modul a:

from foo import bar
bar = "oranges"

Tidak ada kode di luar bilah yang akan melihat "jeruk" karena pengaturan bilah saya hanya memengaruhi nama "bilah" di dalam modul a, itu tidak "menjangkau" objek modul foo dan memperbarui "bilah" -nya.

Michael Ray Lovett
sumber
Dengan contoh terakhir itu, bisakah Anda masih memanggil 'foo.bar = "orange"' untuk memperbarui 'bar' di dalam 'foo'?
velocirabbit
4
Tidak, dalam contoh terakhir, nama 'foo' tidak diketahui
Ghislain Leveque
31
Jawaban INI memberikan jawaban "benar" pada pertanyaan: apa perbedaan antara dua varian impor
Mayou36
3
Menulis beberapa cuplikan untuk membuktikan jawaban ini benar, tetapi apa alasan di balik ini?
huangbeidu
Saya pikir apa yang Anda katakan adalah impor nama simbol untuk memiliki variabel lokal tetapi impor nama modul untuk memiliki variabel global ???
WinEunuuchs2Unix
79

Meskipun banyak orang sudah menjelaskan tentang importvs import from, saya ingin mencoba menjelaskan lebih banyak tentang apa yang terjadi di bawah tenda, dan di mana semua tempat itu berubah berada.


import foo:

Mengimpor foo, dan membuat referensi ke modul itu di namespace saat ini. Kemudian Anda perlu mendefinisikan jalur modul yang telah selesai untuk mengakses atribut atau metode tertentu dari dalam modul.

Misalnya foo.bartetapi tidakbar

from foo import bar:

Impor foo, dan buat referensi ke semua anggota yang terdaftar ( bar). Tidak mengatur variabel foo.

Misalnya bartetapi tidak bazataufoo.baz

from foo import *:

Mengimpor foo, dan membuat referensi ke semua objek publik yang ditentukan oleh modul itu di namespace saat ini (semua yang terdaftar __all__jika __all__ada, jika tidak semua yang tidak dimulai dengan _). Tidak mengatur variabel foo.

Misal bardan baztapi tidak _quxatau foo._qux.


Sekarang mari kita lihat kapan kita melakukannya import X.Y:

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

Periksa sys.modulesdengan nama osdan 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'>

Periksa globals()dan locals()dict namespace dengan osdan 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'
>>>

Dari contoh di atas kami menemukan bahwa hanya osdimasukkan dalam namespace lokal dan global. Jadi, kita harus dapat menggunakan:

 >>> 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'>
 >>>

Tapi tidak path.

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

Setelah Anda menghapus osnamespace dari lokal (), Anda tidak akan dapat mengakses osjuga os.pathmeskipun mereka ada di 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
>>>

Sekarang mari kita bicara tentang import from:

from:

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

Periksa sys.modulesdengan osdan 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'>

Kami menemukan bahwa dalam sys.moduleskami menemukan sama seperti yang kami lakukan sebelumnya dengan menggunakanimport name

OK, mari kita periksa seperti apa dict locals()dan globals()namespace dicts:

>>> 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'
>>>

Anda dapat mengakses dengan menggunakan nama pathbukan dengan 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
>>>

Mari kita hapus 'path' dari locals():

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

Satu contoh terakhir menggunakan 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'>
>>>

Dan tidak ada jalur yang ditentukan:

>>> globals()['path']
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 'path'
>>>
James Sapam
sumber
8
Meskipun ini verbose, ini benar-benar jawaban terbaik dalam daftar untuk pertanyaan yang cukup kompleks. Ini memberikan kode aktual untuk membantu menjelaskan seluk-beluk "di bawah tenda", yang lebih penting daripada gaya, untuk masalah khusus ini. Saya berharap saya bisa lebih baik sekali!
Mike Williamson
Apakah menggunakan as SYMBOLperubahan cara kerja jawaban ini?
Maximilian Burszley
40

Kedua cara didukung karena suatu alasan: ada saat-saat ketika satu lebih tepat daripada yang lain.

  • import module: bagus ketika Anda menggunakan banyak bit dari modul. Kekurangannya adalah bahwa Anda harus memenuhi syarat setiap referensi dengan nama modul.

  • from module import ...: bagus karena barang yang diimpor dapat digunakan langsung tanpa awalan nama modul. Kekurangannya adalah Anda harus membuat daftar setiap hal yang Anda gunakan, dan tidak jelas dalam kode dari mana sesuatu berasal.

Yang digunakan tergantung pada yang membuat kode jelas dan mudah dibaca, dan memiliki lebih dari sedikit hubungannya dengan preferensi pribadi. Saya condong ke arah import moduleumumnya karena dalam kode itu sangat jelas dari mana objek atau fungsi berasal. Saya menggunakan from module import ...ketika saya menggunakan beberapa objek / fungsi banyak dalam kode.

dwc
sumber
1
Apakah ada cara untuk menggunakan from M import Xdan masih mendapatkan manfaat dari menggunakan kualifikasi? Sepertinya Anda bisa mendapatkan yang terbaik dari kedua dunia jika Anda masih bisa melakukannya M.Xsetelah impor itu.
arthropod
@artgropod: Agak. Anda bisa melakukannya class m: from something.too.long import x, y, z. Tidak akan benar-benar merekomendasikan itu.
Lie Ryan
35

Saya pribadi selalu menggunakan

from package.subpackage.subsubpackage import module

dan kemudian akses semuanya sebagai

module.function
module.modulevar

dll. Alasannya adalah bahwa pada saat yang sama Anda memiliki doa pendek, dan Anda dengan jelas mendefinisikan namespace modul setiap rutin, sesuatu yang sangat berguna jika Anda harus mencari penggunaan modul yang diberikan di sumber Anda.

Tidak perlu dikatakan, jangan gunakan impor *, karena itu mencemari namespace Anda dan tidak memberi tahu Anda dari mana fungsi yang diberikan berasal (dari modul mana)

Tentu saja, Anda dapat menjalankan masalah jika Anda memiliki nama modul yang sama untuk dua modul berbeda dalam dua paket berbeda, misalnya

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

dalam hal ini, tentu saja Anda mengalami masalah, tetapi kemudian ada petunjuk kuat bahwa tata letak paket Anda cacat, dan Anda harus memikirkannya kembali.

Stefano Borini
sumber
10
Dalam kasus terakhir, Anda selalu dapat menggunakan: import pkgN.sub.module sebagai modN memberi Anda nama yang berbeda untuk setiap modul. Anda juga dapat menggunakan pola 'import modulename as mod1' untuk mempersingkat nama panjang, atau untuk beralih di antara implementasi API yang sama (mis. Modul DB API) dengan perubahan nama tunggal.
Jeff Shannon
15
import module

Lebih baik bila Anda akan menggunakan banyak fungsi dari modul.

from module import function

Yang terbaik adalah ketika Anda ingin menghindari polusi namespace global dengan semua fungsi dan tipe dari modul saat Anda hanya perlu function.

Andrew Hare
sumber
7
Tentunya satu-satunya hal di namespace global jika Anda melakukan 'modul impor' adalah 'modul'? Anda hanya mencemari namespace jika Anda melakukan 'dari .. impor *'.
John Fouhy
10

Saya baru saja menemukan satu lagi perbedaan halus antara kedua metode ini.

Jika modul foomenggunakan impor berikut:

from itertools import count

Kemudian modul bardapat digunakan tanpa sengaja countseolah-olah itu didefinisikan foo, bukan di itertools:

import foo
foo.count()

Jika foomenggunakan:

import itertools

kesalahan masih mungkin terjadi, tetapi kecil kemungkinannya untuk dilakukan. barperlu:

import foo
foo.itertools.count()

Ini menyebabkan beberapa masalah bagi saya. Saya memiliki modul yang secara tidak sengaja mengimpor pengecualian dari modul yang tidak mendefinisikannya, hanya mengimpornya dari modul lain (menggunakan from module import SomeException). Ketika impor tidak lagi diperlukan dan dihapus, modul yang melanggar rusak.

Jan Wrobel
sumber
10

Inilah perbedaan lain yang tidak disebutkan. Ini disalin kata demi kata dari http://docs.python.org/2/tutorial/modules.html

Perhatikan bahwa saat menggunakan

from package import item

item dapat berupa submodule (atau subpackage) dari paket, atau nama lain yang didefinisikan dalam paket, seperti fungsi, kelas atau variabel. Pernyataan impor terlebih dahulu menguji apakah item tersebut didefinisikan dalam paket; jika tidak, ini dianggap sebagai modul dan mencoba memuatnya. Jika gagal menemukannya, pengecualian ImportError dimunculkan.

Sebaliknya, ketika menggunakan sintaks suka

import item.subitem.subsubitem

setiap item kecuali yang terakhir harus berupa paket; item terakhir bisa berupa modul atau paket tetapi tidak bisa berupa kelas atau fungsi atau variabel yang didefinisikan dalam item sebelumnya.

pengguna2141737
sumber
Hal lain yang saya perhatikan adalah bahwa jika item juga merupakan submodule di dalam paket maka "dari paket impor item" berfungsi tetapi "impor paket" package.item.subitem = ... tidak bekerja dengan init kosong .py paket, kecuali kita memiliki "impor item" di file init paket.
Amitoz Dandiana
6

Karena saya juga seorang pemula, saya akan mencoba menjelaskan ini dengan cara sederhana: Dengan Python, kami memiliki tiga jenis importpernyataan yaitu:

1. Impor generik:

import math

jenis impor ini adalah favorit pribadi saya, satu-satunya kelemahan dari teknik impor ini adalah bahwa jika Anda perlu menggunakan fungsi modul apa pun, Anda harus menggunakan sintaks berikut:

math.sqrt(4)

tentu saja, ini meningkatkan upaya pengetikan tetapi sebagai pemula, ini akan membantu Anda untuk melacak modul dan fungsi yang terkait dengannya, (editor teks yang baik akan mengurangi upaya pengetikan secara signifikan dan direkomendasikan).

Upaya pengetikan selanjutnya dapat dikurangi dengan menggunakan pernyataan impor ini:

import math as m

sekarang, alih-alih menggunakan, math.sqrt()Anda dapat menggunakanm.sqrt() .

2. Fungsi impor:

from math import sqrt

jenis impor ini paling cocok jika kode Anda hanya perlu mengakses satu atau beberapa fungsi dari modul, tetapi untuk menggunakan item baru dari modul Anda harus memperbarui pernyataan impor.

3. Impor universal:

from math import * 

Meskipun ini mengurangi upaya pengetikan secara signifikan tetapi tidak direkomendasikan karena akan mengisi kode Anda dengan berbagai fungsi dari modul dan namanya dapat bertentangan dengan nama fungsi yang ditentukan pengguna. contoh:

Jika Anda memiliki fungsi sqrt Anda sendiri bernama dan Anda mengimpor matematika, fungsi Anda aman: ada sqrt Anda dan ada math.sqrt. Namun, jika Anda melakukannya dari impor matematika *, Anda memiliki masalah: yaitu, dua fungsi berbeda dengan nama yang persis sama. Sumber: Codecademy

Shashank Rawat
sumber
5
import package
import module

Dengan import, token harus berupa modul (file yang berisi perintah Python) atau paket (folder dalam file yang sys.pathberisi __init__.py.)

Ketika ada sub paket:

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

persyaratan untuk folder (paket) atau file (modul) sama, tetapi folder atau file harus di dalam package2yang harus di dalam package1, dan keduanya package1dan package2harus berisi __init__.pyfile. https://docs.python.org/2/tutorial/modules.html

Dengan fromgaya impor:

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

paket atau modul memasuki namespace file yang berisi importpernyataan sebagai module(atau package) alih-alih package1.package2.module. Anda selalu dapat mengikat ke nama yang lebih nyaman:

a = big_package_name.subpackage.even_longer_subpackage_name.function

Hanya fromgaya impor yang memungkinkan Anda menyebutkan nama fungsi atau variabel tertentu:

from package3.module import some_function

diizinkan, tetapi

import package3.module.some_function 

tidak diizinkan.

Bennett Brown
sumber
4

Untuk menambah apa yang dikatakan orang tentang from x import *: selain membuatnya lebih sulit untuk mengetahui dari mana nama berasal, ini melempar pemeriksa kode seperti Pylint. Mereka akan melaporkan nama-nama itu sebagai variabel yang tidak ditentukan.

DNS
sumber
3

Jawaban saya sendiri untuk ini sebagian besar tergantung pada pertama, berapa banyak modul yang berbeda yang akan saya gunakan. Jika saya hanya akan menggunakan satu atau dua, saya akan sering menggunakan from... importkarena itu membuat penekanan tombol lebih sedikit di sisa file, tetapi jika saya akan menggunakan banyak modul yang berbeda, saya lebih suka hanya importkarena itu berarti bahwa setiap referensi modul mendokumentasikan diri. Saya bisa melihat dari mana setiap simbol berasal tanpa harus berburu.

Biasanya saya lebih suka gaya dokumentasi impor diri dan hanya mengubah dari .. impor ketika berapa kali saya harus mengetik nama modul tumbuh di atas 10 hingga 20, bahkan jika hanya ada satu modul yang diimpor.

SingleNegationElimination
sumber
1

Salah satu perbedaan signifikan yang saya temukan yang secara mengejutkan tidak ada yang berbicara adalah menggunakan impor biasa Anda dapat mengakses private variabledan private functionsdari modul impor, yang tidak mungkin dengan pernyataan dari-impor .

masukkan deskripsi gambar di sini

Kode dalam gambar:

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
Saurav Sahu
sumber
0

Modul Impor - Anda tidak perlu upaya tambahan untuk mengambil hal lain dari modul. Ini memiliki kelemahan seperti mengetik berlebihan

Modul Impor Dari - Kurang mengetik & Lebih banyak kontrol terhadap item modul mana yang dapat diakses. Untuk menggunakan item baru dari modul, Anda harus memperbarui pernyataan impor Anda.

Dlucidone
sumber
0

Ada beberapa modul builtin yang sebagian besar berisi fungsi telanjang ( base64 , matematika , os , shutil , sys , time , ...) dan jelas merupakan praktik yang baik untuk memiliki fungsi telanjang ini terikat ke beberapa namespace dan dengan demikian meningkatkan keterbacaan Anda kode. Pertimbangkan betapa sulitnya memahami makna fungsi-fungsi ini tanpa ruang namanya:

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

daripada ketika mereka terikat pada beberapa modul:

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

Kadang-kadang Anda bahkan perlu namespace untuk menghindari konflik antara modul yang berbeda ( json.load vs pickle.load )


Di sisi lain ada beberapa modul yang sebagian besar berisi kelas ( configparser , datetime , tempfile , zipfile , ...) dan banyak dari mereka membuat nama kelas mereka cukup jelas:

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

jadi bisa ada perdebatan apakah menggunakan kelas-kelas ini dengan namespace modul tambahan dalam kode Anda menambahkan beberapa informasi baru atau hanya memperpanjang kode.

Jeyekomon
sumber
0

Saya ingin menambahkan ini, ada beberapa hal yang perlu dipertimbangkan selama panggilan impor:

Saya memiliki struktur berikut:

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 menunjukkan perbedaan:

  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)

Pada akhirnya mereka terlihat sama (STORE_NAME adalah hasil dalam setiap contoh), tetapi ini patut dicatat jika Anda perlu mempertimbangkan empat impor melingkar berikut:

Contoh 1

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

Ini bekerja

contoh2

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'

Tidak ada dadu

contoh3

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

Masalah serupa ... tetapi jelas dari x impor y tidak sama dengan impor impor xy sebagai y

contoh4

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

Yang ini juga berfungsi

ahfx
sumber
0

Ini adalah struktur direktori saya dari direktori saya saat ini:

.  
└─a  
   └─b  
     └─c
  1. The importPernyataan mengingat semua nama menengah .
    Nama-nama ini harus memenuhi syarat:

    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. The from ... import ...pernyataan ingat hanya nama diimpor .
    Nama ini tidak boleh memenuhi syarat:

    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)>

  • Catatan: Tentu saja, saya me-restart konsol Python saya antara langkah 1 dan 2.
MarianD
sumber
0

Seperti yang dikatakan Jan Wrobel , satu aspek dari impor yang berbeda adalah cara pengungkapan impor.

Modul mymath

from math import gcd
...

Penggunaan mymath :

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

Jika saya mengimpor gcdhanya untuk penggunaan internal, bukan untuk mengungkapkannya kepada pengguna mymath, ini bisa merepotkan. Saya sering melakukannya, dan dalam banyak kasus saya ingin "menjaga modul saya tetap bersih".

Terlepas dari usulan Jan Wrobel untuk mengaburkan ini sedikit lebih banyak dengan menggunakan import mathsebagai gantinya, saya sudah mulai menyembunyikan impor dari pengungkapan dengan menggunakan garis bawah utama:

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

Dalam proyek yang lebih besar, "praktik terbaik" ini memungkinkan saya untuk mengontrol dengan tepat apa yang diungkapkan pada impor berikutnya dan apa yang tidak. Ini menjaga modul saya bersih dan membayar kembali pada ukuran proyek tertentu.

matheburg
sumber