Birisi Python'da __all__'yi açıklayabilir mi?


983

Python'u giderek daha fazla kullanıyorum ve değişkenin __all__farklı __init__.pydosyalarda kümesini görmeye devam ediyorum . Birisi bunun ne yaptığını açıklayabilir mi?

Yanıtlar:


566

Bu modülün yorumladığı şekliyle genel nesnelerin bir listesidir import *. Alt çizgi ile başlayan her şeyi gizleme varsayılanını geçersiz kılar.


146
Altçizgi ile başlayan ya da __all__varsa belirtilmeyen nesneler __all__tam olarak gizli değildir; isimlerini biliyorsanız normal şekilde mükemmel şekilde görülebilir ve erişilebilir. Sadece, zaten tavsiye edilmeyen bir "ithal *" durumunda, ayrımın herhangi bir ağırlık taşıması söz konusudur.
Brandon Rhodes

28
@BrandonRhodes: bu da tam olarak doğru değil: Yalnızca tasarlandığını bildiğiniz modülleri import *(örn tk. Gibi ) içe aktarmanız önerilir . Bu durumda, __all__modülün kodunda alt çizgi ile başlayan veya isimler varsa iyi bir ipucu .
uçan koyun

12
Genel ve dahili arabirimler - python.org/dev/peps/pep-0008/#id50 , İçgözlemi daha iyi desteklemek için modüller, __all__ özniteliğini kullanarak genel API'larındaki adları açıkça bildirmelidir. __All__ öğesini boş bir listeye ayarlamak, modülün genel API'sı olmadığını gösterir.
hata ayıklama

tkBugün (veya 2012'de bile) yayınlandıysa, önerilen uygulamanın kullanmak olacağından emin değilim from tk import *. Bence uygulama kasıtlı tasarım değil atalet nedeniyle kabul edildi.
chepner

BrandonRhodes'in işaret ettiği gibi bu gerçekten doğru değil
duhaime

947

Bağlantılı, ancak burada açıkça belirtilmemiş, tam olarak ne zaman __all__kullanılır. Modülde kullanıldığında bir modülde hangi sembollerin dışa aktarılacağını tanımlayan dizelerin bir listesidir from <module> import *.

Örneğin, aşağıdaki kod foo.pyaçıkça sembolleri barve dışa aktarır baz:

__all__ = ['bar', 'baz']

waz = 5
bar = 10
def baz(): return 'baz'

Bu semboller daha sonra şu şekilde içe aktarılabilir:

from foo import *

print(bar)
print(baz)

# The following will trigger an exception, as "waz" is not exported by the module
print(waz)

Eğer __all__yukarıdaki dışarı yorum varsayılan davranışı olarak, bu kod, sonra tamamlanma çalıştırır import *verilen ad alanından, bir alt çizgi ile başlar olmayan tüm sembolleri içe aktarmaktır.

Referans: https://docs.python.org/tutorial/modules.html#importing-from-a-package

NOT: yalnızca davranışı __all__etkiler from <module> import *. Bahsi geçmeyen üyeler __all__modül dışından hala erişilebilir durumdadırlar from <module> import <member>.


1
baz'ı basmamalı mıyız print(baz())?
John Cole

@JohnCole baz fonksiyon nesnesidir ve baz () fonksiyon nesnesini çalıştıracaktır
Bhanu Tez

@BhanuTez tam olarak. Yani print(baz)böyle bir şey yazdırır <function baz at 0x7f32bc363c10>oysa print(baz())baskılarbaz
John Cole

223

__All__ 'i Python'da açıkla?

Değişkenleri __all__farklı __init__.pydosyalarda görmeye devam ediyorum .

Bu ne yapar?

Ne yapar __all__?

Bir modülden anlamsal olarak "ortak" adları bildirir. __all__İçinde bir ad varsa , kullanıcıların onu kullanması beklenir ve değişmeyeceği beklentisine sahip olabilirler.

Ayrıca programatik etkileri olacaktır:

import *

__all__bir modülde, örneğin module.py:

__all__ = ['foo', 'Bar']

import *modülden geldiğinizde , yalnızca içindeki isimlerin __all__içe aktarıldığı anlamına gelir :

from module import *               # imports foo and Bar

Dokümantasyon araçları

Belgeler ve kod otomatik tamamlama araçları, __all__bir modülde hangi adların gösterileceğini belirlemek için de (aslında gerekir) denetleyebilir .

__init__.py bir dizini Python paketi yapar

Gönderen docs :

__init__.pyDosyaları Python tedavi paket içeren dizinleri yapmaları gerekmektedir; bu, dize gibi ortak bir ada sahip dizinlerin, daha sonra modül arama yolunda gerçekleşen geçerli modülleri yanlışlıkla gizlemesini önlemek için yapılır.

En basit durumda, __init__.pyboş bir dosya olabilir, ancak paket için başlatma kodunu yürütebilir veya __all__değişkeni ayarlayabilir .

Böylece bir paket için __init__.pyilan edebilir .__all__

Bir API'yi yönetme:

Bir paket genellikle birbirini içe aktarabilen, ancak mutlaka bir __init__.pydosyayla birbirine bağlanan modüllerden oluşur . Bu dosya dizini gerçek bir Python paketi yapan şeydir. Örneğin, bir pakette aşağıdaki dosyaların bulunduğunu varsayalım:

package
├── __init__.py
├── module_1.py
└── module_2.py

Bu dosyaları Python ile oluşturalım, böylece takip edebilirsiniz - aşağıdakileri bir Python 3 kabuğuna yapıştırabilirsiniz:

from pathlib import Path

package = Path('package')
package.mkdir()

(package / '__init__.py').write_text("""
from .module_1 import *
from .module_2 import *
""")

package_module_1 = package / 'module_1.py'
package_module_1.write_text("""
__all__ = ['foo']
imp_detail1 = imp_detail2 = imp_detail3 = None
def foo(): pass
""")

package_module_2 = package / 'module_2.py'
package_module_2.write_text("""
__all__ = ['Bar']
imp_detail1 = imp_detail2 = imp_detail3 = None
class Bar: pass
""")

Ve şimdi paketinizi içe aktarırken başka birinin kullanabileceği tam bir API sundunuz, şöyle:

import package
package.foo()
package.Bar()

Ve paket, packagead alanınızı doldururken modüllerinizi oluştururken kullandığınız diğer tüm uygulama ayrıntılarına sahip olmayacaktır .

__all__ içinde __init__.py

Daha fazla işten sonra, modüllerin çok büyük olduğuna (binlerce satır gibi?) Ve ayrılmaya karar verdiniz. Böylece aşağıdakileri yaparsınız:

package
├── __init__.py
├── module_1
│   ├── foo_implementation.py
│   └── __init__.py
└── module_2
    ├── Bar_implementation.py
    └── __init__.py

Öncelikle modüllerle aynı adlara sahip alt paket dizinlerini yapın:

subpackage_1 = package / 'module_1'
subpackage_1.mkdir()
subpackage_2 = package / 'module_2'
subpackage_2.mkdir()

Uygulamaları taşıma:

package_module_1.rename(subpackage_1 / 'foo_implementation.py')
package_module_2.rename(subpackage_2 / 'Bar_implementation.py')

her biri için __init__.pybildirilen alt paketler için s oluşturun __all__:

(subpackage_1 / '__init__.py').write_text("""
from .foo_implementation import *
__all__ = ['foo']
""")
(subpackage_2 / '__init__.py').write_text("""
from .Bar_implementation import *
__all__ = ['Bar']
""")

Ve şimdi hala paket düzeyinde API sağladınız:

>>> import package
>>> package.foo()
>>> package.Bar()
<package.module_2.Bar_implementation.Bar object at 0x7f0c2349d210>

Ayrıca API'nize, alt paketin modül düzeyi yerine alt paket düzeyinde yönetebileceğiniz şeyler ekleyebilirsiniz. API'ya yeni bir ad eklemek isterseniz __init__.py, örneğin modül_2'de güncellemeniz yeterlidir:

from .Bar_implementation import *
from .Baz_implementation import *
__all__ = ['Bar', 'Baz']

BazÜst düzey API'da yayınlamaya hazır değilseniz, üst düzeyinizde __init__.pysahip olabilirsiniz:

from .module_1 import *       # also constrained by __all__'s
from .module_2 import *       # in the __init__.py's
__all__ = ['foo', 'Bar']     # further constraining the names advertised

ve kullanıcılarınız kullanılabilirliğinin farkındaysa Bazkullanabilirler:

import package
package.Baz()

ama eğer bilmiyorlarsa, diğer araçlar ( pydoc gibi ) onları bilgilendirmez.

Daha sonra Baz, prime time için hazır olduğunda bunu değiştirebilirsiniz :

from .module_1 import *
from .module_2 import *
__all__ = ['foo', 'Bar', 'Baz']

Prefixing _karşı __all__:

Varsayılan olarak, Python ile başlamayan tüm adları dışa aktarır _. Kesinlikle olabilir Bu mekanizma güveniyor. Python standart kütüphanesinde Bazı paketler, aslında, do bu itimat, ancak, örneğin, bunların ithalatı takma, onlar da yapmak ctypes/__init__.py:

import os as _os, sys as _sys

_Konvansiyonu kullanmak daha zarif olabilir, çünkü isimleri tekrar adlandırmanın artıklığını ortadan kaldırır. Ancak, ithalat için fazlalık ekler (eğer çok fazla varsa) ve bunu tutarlı bir şekilde yapmayı unutmak kolaydır - ve istediğiniz son şey, sadece bir uygulama detayı olmayı amaçladığınız bir şeyi süresiz olarak desteklemektir. çünkü _bir işlevi adlandırırken an önekini unuttun .

__all__Kodlarımı kullanabilecek diğerlerinin ne kullanmaları ve kullanmamaları gerektiğini bilmesi için kişisel olarak modüller için geliştirme yaşam döngümün başlarında yazıyorum .

Standart kitaplıktaki çoğu paket de kullanır __all__.

Kaçınmak __all__mantıklı olduğunda

Aşağıdaki durumlarda _yerine önek kuralına bağlı kalmak mantıklıdır __all__:

  • Hala erken geliştirme modundasınız ve hiç kullanıcınız yok ve API'nızı sürekli değiştiriyorsunuz.
  • Belki kullanıcılarınız var, ancak API'yı kapsayan birim testleriniz var ve hala API'ya aktif olarak ekleniyor ve geliştirmede ince ayar yapıyorsunuz.

Bir exportdekoratör

Kullanmanın dezavantajı, __all__iki kez dışa aktarılan işlevlerin ve sınıfların adlarını yazmanız gerektiğidir - ve bilgiler tanımlardan ayrı tutulur. Biz olabilir bu sorunu çözmek için bir dekoratör kullanın.

David Beazley'in ambalaj konusundaki konuşmasından böyle bir ihracat dekoratörü fikrimi aldım. Bu uygulama CPython'un geleneksel ithalatçısında iyi çalışıyor gibi görünüyor. Özel bir ithalat kancanız veya sisteminiz varsa, bunu garanti etmiyorum, ancak kabul ederseniz, geri çekilmesi oldukça önemsizdir - sadece isimleri manuel olarak__all__

Örneğin, bir yardımcı program kitaplığında dekoratörü tanımlarsınız:

import sys

def export(fn):
    mod = sys.modules[fn.__module__]
    if hasattr(mod, '__all__'):
        mod.__all__.append(fn.__name__)
    else:
        mod.__all__ = [fn.__name__]
    return fn

Bir tanımlarsınız nerede ve ardından __all__, bunu yapmak:

$ cat > main.py
from lib import export
__all__ = [] # optional - we create a list if __all__ is not there.

@export
def foo(): pass

@export
def bar():
    'bar'

def main():
    print('main')

if __name__ == '__main__':
    main()

Ve bu, ana olarak çalıştırılsın veya başka bir işlev tarafından içe aktarılsın.

$ cat > run.py
import main
main.main()

$ python run.py
main

Ve ile API sağlama da import *çalışacaktır:

$ cat > run.py
from main import *
foo()
bar()
main() # expected to error here, not exported

$ python run.py
Traceback (most recent call last):
  File "run.py", line 4, in <module>
    main() # expected to error here, not exported
NameError: name 'main' is not defined

1
Çapraz referans: Dekoratörünüzün nasıl yazılacağı sorusuna bu CW cevabında bahsetmiştim @export.
MvG

13
Bu, tek başına, nispeten yeni bir python geliştiricisinin modül / paket içe aktarma sürecini __init__.pyve kullanımını anlamasına yardımcı olmak için gördüğüm en yararlı cevap oldu__all__
Brett Reinhard

Bu bana çok yardımcı oluyor. Benim sorunum tho, ithal etmek istediğim alt modüllerin hepsinin, manuel __all__olarak doğru olmasını sağlamak zorunda kalmadan, çıkartmak istediğim sembollerinde çok fazla hamle oluşturulmuş dosyalar olduğu.
Mike C

@MikeC sonra belki de sizin üretmek gerekir __all__- ama sonra dengesiz bir API olduğunu söyleyebilirim ... Bu bazı kapsamlı kabul testleri için bir şey olurdu.
Aaron Hall

@AaronHall "diğer isimlere sahip olmayacaklar ... paket ad alanını karıştırıyorlar" Ama isimlere sahip olacaklarmodule_1 ve module_2; o açık içerecek şekilde OK del module_1in __init__.py? Bunun değerli olduğunu düşünmek yanlış mıyım?
Mike C

176

Bunu kesin olarak eklemek istiyorum:

Diğer tüm cevaplar modüllerle ilgilidir . Orijinal soru explicitely sözü __all__de __init__.pydosyalar, bu nedenle bu piton hakkındadır paketleri .

Genellikle, __all__yalnızca devreye girer from xxx import *ve varyant importdeyimi kullanılır. Bu, paketler ve modüller için geçerlidir.

Modüllerin davranışı diğer cevaplarda açıklanmaktadır. Paketler için kesin davranış burada ayrıntılı olarak açıklanmaktadır.

Kısacası, __all__paket seviyesinde , paket içindeki modüller ile ilgilenmesi dışında ( modül içindeki adları belirtmenin aksine) , modüllerle yaklaşık olarak aynı şeyi yapar . Bu nedenle __all__, kullandığımızda geçerli ad alanına yüklenecek ve alınacak tüm modülleri belirtir from package import *.

En büyük fark, bir paketin bildirimini atladığınız zaman , ifadenin hiçbir şey içe aktarmayacağıdır (belgelerde açıklanan istisnalar dışında, yukarıdaki bağlantıya bakın).__all____init__.pyfrom package import *

Öte yandan, __all__bir modülü atlarsanız , "yıldızlı içe aktarma", modülde tanımlanan tüm adları (alt çizgi ile başlayarak değil) içe aktarır.


29
from package import *tanımlanmamış __init__.pyolsa bile, tanımlanan her şeyi içe aktarır all. Önemli fark, onsuz __all__paketin dizininde tanımlanan modülleri otomatik olarak içe aktarmayacağıdır.
Nikratio

Ne zaman tüm Kullandığımız eğer [foo bar] ve test.py dosyada içerir: paket ithalat * dan sonra, foo ve çubuk foo ve barlar kendi ad test.py veya yerel isim alanına alırım?
değişken

87

Ayrıca, pydoc'un göstereceği şeyi değiştirir:

module1.py

a = "A"
b = "B"
c = "C"

module2.py

__all__ = ['a', 'b']

a = "A"
b = "B"
c = "C"

$ pydoc module1

Modül modülü1 ile ilgili yardım:

ADI
    module1

DOSYA
    module1.py

VERİ 
    a = 'A'
     b = 'B'
     c = 'C'

$ pydoc module2

Modül modülü2 ile ilgili yardım:

ADI
    modül2

DOSYA
    module2.py

VERİ 
    __all__ = ['a', 'b']
     a = 'A'
     b = 'B'

__all__Tüm modüllerimde ve dahili detayların altını çizdiğimi beyan ederim, bunlar daha önce canlı tercüman oturumlarında hiç kullanmadığınız şeyleri kullanırken gerçekten yardımcı olur.


54

__all__özelleştirir *içindefrom <module> import *

__all__özelleştirir *içindefrom <package> import *


Bir modül bir olduğunu .pyithal edilecek anlamına dosyası.

Bir paket bir bir dizindir __init__.pydosyası. Bir paket genellikle modüller içerir.


MODÜLLERİ

""" cheese.py - an example module """

__all__ = ['swiss', 'cheddar']

swiss = 4.99
cheddar = 3.99
gouda = 10.99

__all__insanların bir modülün "genel" özelliklerini bilmelerini sağlar . [ @AaronHall ] Ayrıca, pydoc onları tanır. [ @Longpoke ]

dan modül ithalat *

Yerel ad alanına nasıl swissve nasıl cheddargetirildiklerini görün , ancak goudaşunları yapmayın :

>>> from cheese import *
>>> swiss, cheddar
(4.99, 3.99)
>>> gouda
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'gouda' is not defined

Olmadan __all__, herhangi bir sembol (alt çizgi ile başlamayan) mevcut olurdu.


Olmayan ithalatlar *bundan etkilenmez__all__


içe aktarma modülü

>>> import cheese
>>> cheese.swiss, cheese.cheddar, cheese.gouda
(4.99, 3.99, 10.99)

dan modül ithalat adlarıyla

>>> from cheese import swiss, cheddar, gouda
>>> swiss, cheddar, gouda
(4.99, 3.99, 10.99)

modülü yerel ad olarak içe aktar

>>> import cheese as ch
>>> ch.swiss, ch.cheddar, ch.gouda
(4.99, 3.99, 10.99)

PAKETLERİ

In __init__.pya dosyaya paketinde __all__ kamu modülleri veya diğer nesnelerin adları ile dizeleri listesidir. Bu özellikler joker karakterle içe aktarma için kullanılabilir. Modüllerde olduğu gibi , paketten joker karakter içe aktarılırken __all__özelleştirir *. [ @MartinStettner ]

İşte Python MySQL Bağlayıcısı'ndan bir alıntı __init__.py:

__all__ = [
    'MySQLConnection', 'Connect', 'custom_error_exception',

    # Some useful constants
    'FieldType', 'FieldFlag', 'ClientFlag', 'CharacterSet', 'RefreshOption',
    'HAVE_CEXT',

    # Error handling
    'Error', 'Warning',

    ...etc...

    ]

Varsayılan durum, bir paket için yıldız içermeyen__all__ karmaşıktır, çünkü bariz davranış pahalı olacaktır: paketteki tüm modülleri aramak için dosya sistemini kullanmak. Bunun yerine, dokümanları okuduğumda yalnızca içinde tanımlanan nesneler __init__.pyiçe aktarılır:

Eğer __all__tanımlı değil, deyim from sound.effects import *yok değil paketinden tüm submodules içe sound.effectsGeçerli isim haline; yalnızca paketin sound.effectsiçe aktarıldığından (büyük olasılıkla herhangi bir başlatma kodunu çalıştırdığından __init__.py) emin olur ve ardından pakette tanımlanmış olan adları alır. Buna, tarafından tanımlanmış (ve açıkça yüklenen alt modüller) adlar dahildir __init__.py. Ayrıca, önceki içe aktarma ifadeleri tarafından açıkça yüklenmiş olan paketin alt modüllerini de içerir.


Joker karakter ithalatından ... okuyucuları ve birçok otomatik aracı [karıştırdıkları] için kaçınılmalıdır.

[ PEP 8 , @ToolmakerSteve]


2
Gerçekten bu cevap gibi, ama için varsayılan davranış ne dair bilgi eksik from <package> import *olmadan __all__içinde __init__.pyolduğunu modüllerin herhangi ithal değil .
radzak

@ @Jatimir, deneyler yapmadan yapabildiğim kadar iyi açıkladım. Neredeyse bu durumun (bir paket için hepsi olmayan yıldız) bir modül gibi__init__.py davrandığını söylemek istedim . Ancak bunun doğru olduğundan veya özellikle alt çizgi ön ekli nesnelerin hariç tutulduğundan emin değilim. Ayrıca, MODÜLLER ve PAKETLER bölümlerini daha net bir şekilde ayırdım. Senin düşüncelerin?
Bob Stein

49

Gönderen (An Resmi olmayan) Python Referans Wiki :

Bir modül tarafından tanımlanan genel adlar, modülün ad alanı adlı bir değişken olup olmadığına bakılarak belirlenir __all__; tanımlanmışsa, bu modül tarafından tanımlanan veya içe aktarılan isimler olan bir dizi dizisi olmalıdır. Verilen adların __all__tümü herkese açık olarak kabul edilir ve bulunması gerekir. __all__Tanımlı değilse , genel adlar kümesi, modülün ad alanında bulunan ve alt çizgi karakteriyle ("_") başlamayan tüm adları içerir. __all__herkese açık API'yı içermelidir. API'nın bir parçası olmayan öğelerin (modül içinde içe aktarılan ve kullanılan kütüphane modülleri gibi) yanlışlıkla dışa aktarılmasından kaçınılması amaçlanmıştır.


Listelenen bağlantı öldü. ancak vdocuments.net/… ve burada metin kelimesi kelimesine bulundu : dokumen.tips/documents/reference-567bab8d6118a.html
JayRizzo

8

__all__bir Python modülünün genel API'sını belgelemek için kullanılır. İsteğe bağlı olmasına rağmen __all__kullanılmalıdır.

İşte Python dil referansından ilgili alıntı :

Bir modül tarafından tanımlanan genel adlar, modülün ad alanı adlı bir değişken olup olmadığına bakılarak belirlenir __all__; tanımlanmışsa, bu modül tarafından tanımlanan veya içe aktarılan isimler olan bir dizi dizisi olmalıdır. Verilen adların __all__tümü herkese açık olarak kabul edilir ve bulunması gerekir. __all__Tanımlı değilse , genel adlar kümesi, modülün ad alanında bulunan ve alt çizgi karakteriyle ('_') başlamayan tüm adları içerir. __all__herkese açık API'yı içermelidir. API'nın bir parçası olmayan öğelerin (modül içinde içe aktarılan ve kullanılan kütüphane modülleri gibi) yanlışlıkla dışa aktarılmasından kaçınılması amaçlanmıştır.

PEP 8 benzer ifadeler kullanır, ancak içe aktarılan adların yokken genel API'nin bir parçası olmadığını da açıkça belirtir __all__:

İçgözlemi daha iyi desteklemek için modüller, bu __all__özelliği kullanarak genel API'larındaki adları açıkça bildirmelidir . __all__Boş bir listeye ayarlamak , modülün genel API'sı olmadığını gösterir.

[...]

İçe aktarılan adlar her zaman bir uygulama ayrıntısı olarak düşünülmelidir. Diğer modüller, içerilen modülün API'sinin açık bir şekilde belgelenmiş bir parçası os.pathveya __init__alt modüllerden işlevsellik gösteren bir paket modülü olmadıkça, bu tür içe aktarılan adlara dolaylı erişime güvenmemelidir .

Ayrıca, diğer yanıtlarda belirtildiği gibi, paketler için joker karakterle içe aktarmayı__all__ etkinleştirmek için kullanılır :

İmport ifadesi aşağıdaki kuralı kullanır: bir paketin __init__.pykodu adlı bir liste tanımlarsa , karşılaşıldığında __all__alınması gereken modül adlarının listesi olarak alınır from package import *.


8

Kısa cevap

__all__from <module> import *ifadeleri etkiler .

Uzun cevap

Bu örneği düşünün:

foo
├── bar.py
└── __init__.py

İçinde foo/__init__.py:

  • Biz define yoksa (Örtülü) __all__, daha sonra from foo import *sadece tanımlanmış adlar ithal edecek foo/__init__.py.

  • (Açık) Tanımlarsak __all__ = [], from foo import *hiçbir şey içe aktarmaz.

  • Biz tanımlarsanız (Explicit) __all__ = [ <name1>, ... ], daha sonra from foo import *sadece bu isimleri ithal edecek.

Örtük durumda, python ile başlayan adları içe aktarmaz _. Ancak, bu tür adları kullanarak içe aktarmayı zorlayabilirsiniz __all__.

Python belgesini burada görüntüleyebilirsiniz .


5

__all__nasıl from foo import *çalıştığını etkiler .

Bir modül gövdesi içindeki (ancak bir işlev veya sınıf gövdesinde olmayan *) bir fromdeyimde yıldız işareti ( ) kullanabilir :

from foo import *

*Tüm modülün ilişkilendirdiği istekleri foo(alt çizgi olanlar başından hariç) ithal modülünde küresel değişkenler olarak bağlı. Bir fooözniteliğe sahip olduğunda , özniteliğin __all__değeri, bu tür fromifadelerle bağlanan adların listesidir .

Eğer foobir olan paket ve __init__.pytanımlar adında bir liste __all__, zaman ithal edilmelidir alt modülü isimlerinin listesi olarak alınır from foo import *karşılaşılır. Eğer __all__tanımlı değil, deyim from foo import *ne olursa olsun isimleri ithalatı paketinde tanımlanmıştır. Buna, tarafından tanımlanmış (ve açıkça yüklenen alt modüller) adlar dahildir __init__.py.

Bunun __all__bir liste olması gerekmediğini unutmayın . Belgelere uyarınca importaçıklamada , tanımlanan eğer __all__bir olmalıdır dizeleri dizisi modülü tarafından tanımlanmış veya ithal isimlerdir. Bu nedenle, bazı bellek ve CPU döngülerini kaydetmek için bir demet kullanabilirsiniz . Modülün tek bir ortak ad tanımlaması durumunda virgül kullanmayı unutmayın:

__all__ = ('some_name',)

Ayrıca bkz. “İçe aktarma *” neden kötü?


1

Bu burada PEP8'de tanımlanmıştır :

Global Değişken İsimleri

(Bu değişkenlerin yalnızca bir modül içinde kullanılması amaçlandığını umalım.) Kurallar, işlevler ile hemen hemen aynıdır.

Aracılığıyla kullanılmak üzere tasarlanmış modüller, küreselleri dışa aktarmayı önlemek from M import *için __all__mekanizmayı kullanmalı veya bu küreselleri alt çizgiyle önekleme eski kuralını kullanmalıdır (bu küresellerin "halka açık değil" olduğunu belirtmek isteyebilirsiniz).

PEP8, ana Python dağıtımında standart kütüphaneyi içeren Python kodu için kodlama kuralları sağlar. Bunu ne kadar çok takip ederseniz, orijinal niyetinize o kadar yakın olursunuz.

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.