Python modülleri neden bazen alt modüllerini içe aktarmıyor?


91

Bugün açıklanmasını istediğim garip bir şey fark ettim. Bunu bir soru olarak nasıl ifade edeceğime% 100 emin değildim, bu yüzden google söz konusu değil. Günlük modülü, bazı garip nedenlerden dolayı logging.handlers modülüne erişemiyor. Bana inanmıyorsanız kendiniz deneyin:

>>> import logging
>>> logging.handlers
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'handlers'
>>> import logging.handlers
>>> logging.handlers
<module 'logging.handlers' from '/usr/lib/python2.6/logging/handlers.pyc'>

Bunun neden olduğunu kimse açıklayabilir mi?

Yanıtlar:


122

Python'da, modüllerin erişilebilir olmadan önce içe aktarılması gerekir. import loggingyalnızca günlük modülünü içe aktarır. Bu logging, alt modülleri olan bir pakettir, ancak bu alt modüller yine de otomatik olarak yüklenmez. Bu nedenle, logging.handlerserişmeden önce açıkça içe aktarmanız gerekir.

Neden bazen bu ekstra içe aktarmalara ihtiyacınız yok gibi göründüğünü merak ediyorsanız: bazı paketler, alt modüllerinin bir kısmını veya tamamını içe aktarılırken içe aktarır - sadece __init__.pydosyalarında bu içe aktarmaları yaparak . Diğer durumlarda, içe aktardığınız başka bir şey de içe aktarılmış olabilir logging.handlers. İçe aktarımın hangi kod parçasını yaptığı önemli değildir; Uzun olduğunca şey sizin süreç ithalatta logging.handlerssiz erişmeden önce, orada olacağım. Ve bazen bir paket gibi görünüyor gerçekten gibi tek bir modül olmadığını osve os.path. osbir paket değil, sadece doğru diğer modülü (platformunuz için) içe aktarır ve çağırır path, böylece ona erişebilirsiniz os.path.


4

Python'da yeniyim ve çok fazla pratik yaptıktan sonra artık paket (klasör), modül (.py), sınıflar, değişkenler ... vb.

klasörünüzden herhangi birinin python paketi olmasını istiyorsanız - __init__.pyDosya içermesi gerekir, boş dosya bile işe yarar !!!

ve Thomas'ın dediği gibi, isterseniz __init__.py'ye fazladan modül aktarabilirsiniz !!! ancak modüllere / paketlere ancak içe aktarıldıktan sonra erişilebilir ...

her şeyi bir modülden içe aktarmak istiyorsanız kullanabilirsiniz

from logging import *

geri kalanı da aşağıdaki gibi işleyici modülüne erişebilirsiniz,

from logging import handlers
print dir(handlers)


5
Lütfen kullanmayın from module import *. Neredeyse her zaman bir hatadır.
Thomas Wouters

Eğer bir paket içinde her şey otomatik olarak içe olmak istiyorsanız bu ithalat yapmak init yerine ayar, .py tüm içinde init .py ve yapıyor 'paketi import *' bir yerlerde.
Thomas Wouters

2
@Pete: çünkü belirsizliğe ve çatışmaya yol açan standart isim alanını "kirletiyor". Olsaydı import zipperve zipper.open()tam olarak hangi açık aradığımı bilseydin. Tersine from zipper import *, ardından open()da yerleşik açık veya zipper.open veya başka bir şey. import zipper as zEğer yazarak yorgun olsun çok tercih edilirzipper
MSW

3
@Pete: Bu aynı zamanda bir problem çünkü bilmeden ad alanınızın bazılarının üzerine yazabilirsiniz. Ben kullanmak için kullanılan numpy import *Eğer (IMO kendi tarafında korkunç tasarım hatası) Numpy tümünü almak sürece bazı numpy fonksiyonlar işi yok çünkü ama numpy nesneler o ithalatı bir BÜYÜK numarası vardır. Pek çok işlevin üzerine yazdım (kopyalamanın bir olduğuna inanıyorum ... Kontrol edemeyecek kadar yoruldum). Şimdi numpy'yi np olarak içe aktarıyorum, eğer numpy'yi o kadar çok kullanacaksam, tekrar tekrar yazmaya dayanamıyorum.
chriscauley

2
@dustynachos, hangi numpy işlevi bu kusura sahip?
Winston Ewert

2

Thomas Wouters bu soruyu çok iyi cevapladı, ancak ne yazık ki, bu soruyu ancak orijinal belgede cevabı bulduktan sonra buldum. Bu amaçla, gelecekte arama motorunun tepesine daha yakın bir şekilde ortaya çıkması umuduyla buna ekleyeceğimi düşündüm.

SORU

Neden hatayı yapar: ' AttributeError: modül' modül_ismi 'hayır nitelik vardır' sub_module_name 'bile benim editör olsa görünür (örneğin Görsel Kod) otomatik tamamlar alt modül adı:

 import module_name
 module_name.sub_module_name(parameter)

CEVAP

Düzenleyiciniz otomatik tamamlamayı Python davranışından değil, projenizin dosya yapısına dayandırıyor. Bir modülü içe aktardığınızda alt modüller 'otomatik olarak' içe aktarılmaz. Referans Python Belgeler nasıl 'otomatik' ithalat alt modüllere ilişkin ayrıntılar için kullanıyor

 import module_name

Bu cevabın temel katkısı, bir 'modül' veya 'paket' içe aktarmaya çalışırken AttributeError'ın eklenmesi

Umarım bu birine yardımcı olur!


1

Geçenlerde aynı tuhaf durumla karşılaştım. Yani, bahse girerim bazı üçüncü taraf kitaplık içe aktarmayı kaldırmışsınızdır. Bu, lib'yi içeren from logging import handlersveya from logging import *size sağladı handlers. Ve başka bir senaryoda, benzer bir şeye sahiptiniz import loggingve sadece kullandınız logging.handlersve bunun benim yaptığım gibi işleyişinin bir yolu olduğunu düşündünüz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.