යමෙකුට පයිතන් හි __all__ පැහැදිලි කළ හැකිද?


1021

මම වැඩි වැඩියෙන් පයිතන් භාවිතා කර ඇති __all__අතර, විවිධ __init__.pyගොනු වල විචල්‍ය කට්ටලය මම දකිමි. මෙය කරන්නේ කුමක්දැයි යමෙකුට පැහැදිලි කළ හැකිද?

Answers:


599

එය අර්ථකථනය කර ඇති පරිදි එම මොඩියුලයේ පොදු වස්තු ලැයිස්තුවකි import *. අවධාරනයකින් ආරම්භ වන සියල්ල සැඟවීමේ පෙරනිමිය එය අභිබවා යයි.


148
Underscore සමග ආරම්භ, හෝ සඳහන් වී නොමැති බව වස්තූන් __all__නම් __all__වත්මන් වන අතර, හරියටම සඟවා නොමැත; ඔබ ඔවුන්ගේ නම් දන්නේ නම් ඒවා සාමාන්‍යයෙන් දැක බලා ඒවාට ප්‍රවේශ විය හැකිය. කෙසේ වෙතත් නිර්දේශ නොකරන "ආනයනය *" සම්බන්ධයෙන් පමණක් වෙනස ඕනෑම බරක් දරයි.
බ්‍රැන්ඩන් රෝඩ්ස්

28
Ra බ්‍රැන්ඩන් රෝඩ්ස්: එය හරියටම සත්‍ය නොවේ: ඔබ සැලසුම් කර ඇති බව දන්නා මොඩියුල පමණක් ආනයනය කිරීම රෙකමදාරු කරනු ලැබේ import *(උදා tk.). __all__මොඩියුලයේ කේතයේ අවධාරනය කිරීමෙන් ආරම්භ වන නම් හෝ නම් මෙය හොඳ ඉඟියක් වේ .
පියාඹන බැටළුවන්

12
රාජ්ය හා අභ්යන්තර අතුරු මුහුණත් - python.org/dev/peps/pep-0008/#id50 , වඩා හොඳ සහය යෝජනාවලිය භේදභින්න කිරීම සඳහා, මොඩියුල පැහැදිලිව නම්, තම පොදු API හි __all__ විශේෂණය යොදා ප්රකාශ කළ යුතුය. __All__ හිස් ලැයිස්තුවකට සැකසීමෙන් පෙන්නුම් කරන්නේ මොඩියුලයට පොදු API නොමැති බවයි.
නිදොස් කිරීම

tkඅද (හෝ 2012 දී පවා) නිකුත් කරනු ලැබුවහොත් නිර්දේශිත පුහුණුව භාවිතා කිරීම බව මට විශ්වාස නැත from tk import *. මම හිතන්නේ පුහුණුව පිළිගන්නේ අවස්ථිතිත්වය නිසා මිස හිතාමතාම නිර්මාණය කිරීම නිසා නොවේ.
චෙප්නර්

976

මෙහි සම්බන්ධ කර ඇති නමුත් මෙහි නිශ්චිතව සඳහන් කර නොමැති අතර එය හරියටම __all__භාවිතා කරන විට වේ. එය මොඩියුලයේ from <module> import *භාවිතා කරන විට මොඩියුලයක ඇති සංකේත අපනයනය කරන්නේ කෙසේද යන්න නිර්වචනය කරන නූල් ලැයිස්තුවකි .

උදාහරණයක් ලෙස, පහත දැක්වෙන කේතය foo.pyපැහැදිලිවම සංකේත අපනයනය කරයි barසහ baz:

__all__ = ['bar', 'baz']

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

මෙම සංකේත පසුව ආනයනය කළ හැකිය:

from foo import *

print(bar)
print(baz)

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

නම් __all__ඉහත පෙන්වා අදහස් වන්නේ, මෙම කේතය පසුව සම්පූර්ණ කිරීමට, වන පෙර සැකසුම් හැසිරීම ලෙස ක්රියාත්මක වනු ඇත import *ලබා දී නාම සිට, underscore සමග ආරම්භ නැති බව සියලු සංකේත ආනයනය කිරීමට ය.

යොමුව: https://docs.python.org/tutorial/modules.html#importing-from-a-package

සටහන: හැසිරීමට පමණක් __all__බලපායි from <module> import *. සඳහන් කර නොමැති සාමාජිකයින්ට __all__තවමත් මොඩියුලයට පිටතින් පිවිසිය හැකි අතර ඒවා ආනයනය කළ හැකිය from <module> import <member>.


1
අපි බාස් ලෙස මුද්‍රණය කළ යුතු නොවේද print(baz())?
ජෝන් කෝල්

1
@ ජෝන් කෝල් බාස් යනු ක්‍රියාකාරී වස්තුව වන අතර බාස් () ක්‍රියාකාරී වස්තුව ක්‍රියාත්මක කරයි
භානු තේස්

Han භානුටෙස් හරියටම. ඒ නිසා print(baz)වගේ දෙයක් මුද්රණය කරයි <function baz at 0x7f32bc363c10>ෙහයින්ද, print(baz())මුද්රණbaz
ජෝන් කෝල්

1
සංකේතය අපනයනය කරන බව නිදර්ශනය කිරීම අරමුණයි. එය ශ්‍රිතය ක්‍රියාත්මක කළත් නැතත් ද්විතීයික ය.
ඇලෙක් තෝමස්

අද දක්වාම, __all__කාර්යයන් / වස්තූන් සෘජුවම යොමු කිරීමෙන් ජනගහනය වීමට ක්‍රමයක් නොමැති බව මට ප්‍රහේලිකාවක් . ඒ වෙනුවට අපි ඔවුන්ගේ නම් ටයිප් කර නමක් වෙනස් වන ඕනෑම වේලාවක ඒවා නිවැරදි කළ යුතුයි. සක්‍රීය කේත පදනම් සඳහා ඉතා දෝෂ සහිත බව පෙනේ.
ජූලියෝ සීසර් සිල්වා

249

පයිතන්හි __all__ පැහැදිලි කරන්න?

__all__විවිධ __init__.pyලිපිගොනු වල විචල්‍ය කට්ටලය මම දිගටම දකිමි .

මෙය කරන්නේ කුමක්ද?

මොකද කරන්නේ __all__?

එය මොඩියුලයකින් අර්ථාන්විතව “පොදු” නම් ප්‍රකාශ කරයි. තුළ නමක් තිබේ නම් __all__, පරිශීලකයින් එය භාවිතා කිරීමට අපේක්ෂා කරන අතර, එය වෙනස් නොවන බවට ඔවුන්ට අපේක්ෂාවක් තිබිය හැකිය.

එය ක්‍රමලේඛනමය බලපෑම් ද ඇති කරයි:

import *

__all__මොඩියුලයක, උදා module.py:

__all__ = ['foo', 'Bar']

එයින් අදහස් වන්නේ ඔබ import *මොඩියුලයේ සිට __all__ආනයනය කරනු ලබන්නේ එම නම් පමණි :

from module import *               # imports foo and Bar

ප්‍රලේඛන මෙවලම්

__all__මොඩියුලයකින් ලබා ගත හැකි නම් පෙන්විය යුතු නම් මොනවාද යන්න තීරණය කිරීම සඳහා ප්‍රලේඛන සහ කේත ස්වයං සම්පුර්ණ කිරීමේ මෙවලම් (ඇත්ත වශයෙන්ම කළ යුතුය) පරීක්ෂා කළ හැකිය.

__init__.py ඩිරෙක්ටරියක් පයිතන් පැකේජයක් කරයි

සිට ලේඛන :

මෙම __init__.pyගොනු Python පැකේජ අඩංගු ලෙස නාමාවලි ප්රතිකාර කිරීමට අවශ්ය ඇත; මොඩියුලය සෙවුම් මාවතේ පසුව සිදුවන වලංගු මොඩියුලයන් නොදැනුවත්ව සැඟවීමෙන් නූල් වැනි පොදු නාමයක් සහිත නාමාවලි වලක්වා ගැනීම සඳහා මෙය සිදු කෙරේ.

සරලම අවස්ථාවෙහිදී, __init__.pyහිස් ගොනුවක් විය හැකිය, නමුත් එයට පැකේජය සඳහා ආරම්භක කේතය ක්‍රියාත්මක කිරීමට හෝ __all__විචල්‍යය සැකසීමට හැකිය.

එබැවින් පැකේජයක් සඳහා __init__.pyප්‍රකාශ කළ හැකිය .__all__

API කළමනාකරණය:

පැකේජයක් සාමාන්‍යයෙන් සෑදී ඇත්තේ එකිනෙකා ආනයනය කළ හැකි මොඩියුල වලින් වන නමුත් ඒවා අනිවාර්යයෙන්ම __init__.pyගොනුවක් සමඟ බැඳී ඇත . එම ගොනුව නාමාවලිය සත්‍ය පයිතන් පැකේජයක් බවට පත් කරයි. උදාහරණයක් ලෙස, ඔබට පහත ලිපිගොනු පැකේජයක ඇති බව පවසන්න:

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

පයිතන් සමඟ මෙම ලිපිගොනු නිර්මාණය කරමු, එවිට ඔබට අනුගමනය කළ හැකිය - ඔබට පහත සඳහන් දෑ පයිතන් 3 කවචයකට ඇලවිය හැකිය:

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

දැන් ඔබ ඔබේ පැකේජය ආනයනය කිරීමේදී වෙනත් කෙනෙකුට භාවිතා කළ හැකි සම්පූර්ණ api එකක් ඉදිරිපත් කර ඇත:

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

ඔබේ මොඩියුල නිර්මාණය කිරීමේදී packageනාම අවකාශය අවුල් කරමින් ඔබ භාවිතා කළ අනෙකුත් ක්‍රියාත්මක කිරීමේ තොරතුරු පැකේජයේ නොමැත .

__all__ තුල __init__.py

වැඩිපුර වැඩ කිරීමෙන් පසු, මොඩියුල විශාල බව (පේළි දහස් ගණනක් වැනි) ඔබ තීරණය කර ඇති අතර ඒවා බෙදීමට අවශ්‍යය. එබැවින් ඔබ පහත සඳහන් දේ කරයි:

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

පළමුව මොඩියුලවලට සමාන නම් සහිත උප පැකේජ නාමාවලි සාදන්න:

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

ක්‍රියාත්මක කිරීම් ගෙනයන්න:

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

එක් එක් සඳහා __init__.pyප්‍රකාශ කරන උප පැකේජ සඳහා s සාදන්න __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']
""")

දැන් ඔබට තවමත් api ඇසුරුම් මට්ටමින් ලබා දී ඇත:

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

උප පැකේජයේ මොඩියුල මට්ටම වෙනුවට උප පැකේජ මට්ටමින් ඔබට කළමනාකරණය කළ හැකි දේවල් පහසුවෙන් ඔබගේ API වෙත එක් කළ හැකිය. ඔබට API වෙත නව නමක් එක් කිරීමට අවශ්‍ය නම්, ඔබ සරලවම යාවත්කාලීන කරන්න __init__.py, උදා: මොඩියුලය_2:

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

ඔබ Bazඉහළ මට්ටමේ API හි ප්‍රකාශයට පත් කිරීමට සූදානම් නැතිනම් , ඔබේ ඉහළ මට්ටමේ __init__.pyඔබට තිබිය හැක්කේ:

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

සහ ඔබේ පරිශීලකයින් ලබා ගත හැකි බව දැන ගන්නේ නම් Baz, ඔවුන්ට එය භාවිතා කළ හැකිය:

import package
package.Baz()

නමුත් ඔවුන් ඒ ගැන නොදන්නේ නම්, වෙනත් මෙවලම් ( පයිඩොක් වැනි ) ඒවා දැනුම් නොදේ.

Bazප්‍රයිම් ටයිම් සඳහා සූදානම් වන විට ඔබට එය පසුව වෙනස් කළ හැකිය :

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

උපසර්ගය _එදිරිව __all__:

පෙරනිමියෙන්, පයිතන් a සමඟ ආරම්භ නොවන සියලුම නම් අපනයනය කරයි _. ඔබට නිසැකවම මෙම යාන්ත්‍රණය මත විශ්වාසය තැබිය හැකිය . පයිතන් සම්මත පුස්තකාලයේ සමහර පැකේජ ඇත්ත වශයෙන්ම මේ මත රඳා පවතී, නමුත් එසේ කිරීම සඳහා, ඔවුන්ගේ ආනයන අන්වර්ථ කරයි, උදාහරණයක් ලෙස ctypes/__init__.py:

import os as _os, sys as _sys

_සම්මුතිය භාවිතා කිරීම වඩාත් අලංකාර විය හැක්කේ එය නැවත නම් තැබීමේ අතිරික්තය ඉවත් කරන බැවිනි. නමුත් එය ආනයන සඳහා අතිරික්තයක් එක් කරයි (ඔබට ඒවායින් බොහොමයක් තිබේ නම්) මෙය නොකඩවා කිරීමට අමතක කිරීම පහසුය - තවද ඔබට අවශ්‍ය අන්තිම දෙය වන්නේ ක්‍රියාත්මක කිරීමේ විස්තරයක් පමණක් වීමට ඔබ අදහස් කළ දෙයකට දින නියමයක් නොමැතිව සහාය වීමයි. _ශ්‍රිතයක් නම් කිරීමේදී ඔබට උපසර්ගයක් කිරීමට අමතක වූ නිසා .

__all__මොඩියුල සඳහා මගේ සංවර්ධන ජීවන චක්‍රයේ මුල් අවධියේදී මම පෞද්ගලිකව ලියමි, එවිට මගේ කේතය භාවිතා කළ හැකි අනෙක් අය ඔවුන් භාවිතා කළ යුතු දේ සහ භාවිතා නොකළ යුතු දේ දැන ගනී.

සම්මත පුස්තකාලයේ බොහෝ පැකේජ ද භාවිතා කරයි __all__.

වැළකී සිටීම __all__අර්ථවත් කරයි

කවදාද යන්න _වෙනුවට උපසර්ග සම්මුතියට ඇලී සිටීම අර්ථවත් කරයි __all__:

  • ඔබ තවමත් මුල් සංවර්ධන මාදිලියේ සිටින අතර පරිශීලකයින් නොමැති අතර ඔබේ API නිරන්තරයෙන් වෙනස් කරමින් සිටී.
  • සමහර විට ඔබට පරිශීලකයින් සිටී, නමුත් ඔබට ඒපීඅයි ආවරණය කරන යුනිටෙට්ස් ඇති අතර, ඔබ තවමත් ක්‍රියාකාරීව ඒපීඅයි වෙත එකතු කරමින් සංවර්ධනයේ අතුගා දමයි.

exportdecorator

__all__භාවිතයේ අවාසිය නම් අපනයනය කරනු ලබන කාර්යයන් සහ පන්තිවල නම් දෙවරක් ලිවිය යුතු අතර තොරතුරු අර්ථ දැක්වීම් වලින් වෙන්ව තබා ගැනීමයි. අපි හැකි , මෙම ගැටලුව විසඳීම සඳහා decorator භාවිතා කරන්න.

ඩේවිඩ් බීස්ලි ඇසුරුම්කරණය පිළිබඳ කතාවෙන් එවැනි අපනයන සැරසිලි කරුවෙකු සඳහා මට අදහස ලැබුණි. මෙම ක්‍රියාත්මක කිරීම CPython හි සාම්ප්‍රදායික ආනයනකරු තුළ හොඳින් ක්‍රියාත්මක වන බව පෙනේ. ඔබට විශේෂ ආනයන කොක්කක් හෝ පද්ධතියක් තිබේ නම්, මම එය සහතික නොකරමි, නමුත් ඔබ එය සම්මත කර ගන්නේ නම්, පිටතට යාම තරමක් සුළු කාරණයකි - ඔබට නැවත අතින් නම් එකතු කළ යුතුය__all__

උදාහරණයක් ලෙස, උපයෝගිතා පුස්තකාලයක, ඔබ සැරසිලි කරුවා අර්ථ දක්වනු ඇත:

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

ඉන්පසු, ඔබ මෙය අර්ථ දක්වන්නේ කොතැනද __all__, ඔබ මෙය කරන්නේ:

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

මෙය ප්‍රධාන ලෙස ක්‍රියාත්මක වුවද වෙනත් ශ්‍රිතයක් මඟින් ආනයනය කළද මෙය හොඳින් ක්‍රියාත්මක වේ.

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

$ python run.py
main

ඒ සමඟම API ප්‍රතිපාදන සැපයීමද import *ක්‍රියාත්මක වේ:

$ 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
හරස් යොමු: සැරසිලි කරුවෙකු ලියන්නේ කෙසේද යන ප්‍රශ්නයට මෙම සීඩබ්ලිව් පිළිතුරෙහි ඔබේ සැරසිලි කරුවා සඳහන් කළෙමි @export.
එම්වීජී

13
සාපේක්ෂව නව පයිතන් සංවර්ධකයෙකුට මොඩියුල / පැකේජ ආනයනය කිරීමේ ක්‍රියාවලිය __init__.pyසහ භාවිතය පිළිබඳ අවබෝධය ලබා දීම සම්බන්ධයෙන් මා දුටු වඩාත්ම ප්‍රයෝජනවත් පිළිතුර මෙයයි__all__
බ්‍රෙට් රයින්හාර්ඩ්

මෙය මට බොහෝ උපකාර කරයි. මගේ ගැටලුව නම්, මට ආනයනය කිරීමට අවශ්‍ය උප මොඩියුල සියල්ලම __all__නිවැරදි යැයි අතින් සහතික නොකොට, මම ඉවත් කිරීමට කැමති ඒවායේ සංකේතවල විශාල කබොල්ලක් සහිත ජනනය කරන ලද ගොනු වේ.
මයික් සී

IkeMikeC එවිට ඔබත් ඔබේ උත්පාදනය කළ යුතුයි __all__- නමුත් එවිට මම ඔබට කියන්නේ ඔබට අස්ථායී API එකක් ඇති බවයි ... මෙය පුළුල් පිළිගැනීමේ පරීක්ෂණ කිහිපයක් සඳහා යමක් වනු ඇත.
ආරොන් හෝල්

"ඔවුන් පැකේජය නාමඅවකාශයෙහි දක්වා cluttering අනෙකුත් සියලුම නම් සිදු විය යුතු නැහැ ..." @AaronHall එහෙත් ඔවුන් ඇත නම් ඇති module_1හා module_2; එය පැහැදිලි ඇතුළත් කිරීමට හරිද del module_1දී __init__.py? මෙය වටිනවා යැයි සිතීම මා වැරදිද?
මයික් සී

179

මම මෙය නිවැරදිව එකතු කරන්නෙමි:

අනෙක් සියලුම පිළිතුරු මොඩියුල වෙත යොමු වේ . මුල් ප්‍රශ්නය ලිපිගොනු වල පැහැදිලිව සඳහන් කර __all__ඇති __init__.pyබැවින් මෙය පයිතන් පැකේජ ගැන වේ.

සාමාන්‍යයෙන්, ක්‍රියාත්මක __all__වන්නේ ප්‍රකාශයේ from xxx import *ප්‍රභේදය භාවිතා කළ විට පමණි import. මෙය පැකේජ වලට මෙන්ම මොඩියුල සඳහාද අදාළ වේ.

මොඩියුල සඳහා හැසිරීම අනෙක් පිළිතුරු වලින් විස්තර කෙරේ. පැකේජ සඳහා නිශ්චිත හැසිරීම මෙහි විස්තරාත්මකව විස්තර කෙරේ.

කෙටියෙන් කිවහොත්, __all__පැකේජයේ ඇති මොඩියුල සමඟ ගනුදෙනු කිරීම හැර ( මොඩියුලය තුළ නම් සඳහන් කිරීමට වෙනස්ව ) පැකේජ මට්ටමින් මොඩියුල සඳහා සමාන දේම කරයි . එබැවින් __all__අප භාවිතා කරන විට වත්මන් නාම අවකාශයට පටවා ආනයනය කළ යුතු සියලුම මොඩියුල නියම කරයි from package import *.

විශාල වෙනස නම්, ඔබ පැකේජයක ප්‍රකාශය අතහැර දැමූ විට , ප්‍රකාශය කිසිසේත් ආනයනය නොකරනු ඇත (ප්‍රලේඛනයේ දක්වා ඇති ව්‍යතිරේකයන් සමඟ, ඉහත සබැඳිය බලන්න).__all____init__.pyfrom package import *

අනෙක් අතට, ඔබ __all__මොඩියුලයක් අතහැර දැමුවහොත් , "තරු ලකුණු කළ ආනයනය" මොඩියුලයේ අර්ථ දක්වා ඇති සියලුම නම් ආනයනය කරයි (යටි ඉරි වලින් ආරම්භ නොවේ).


29
from package import *__init__.pyනොමැති වුවද, අර්ථ දක්වා ඇති සියල්ල තවමත් ආනයනය කරනු ඇත all. වැදගත් වෙනස නම් එය නොමැතිව __all__පැකේජයේ නාමාවලියෙහි අර්ථ දක්වා ඇති කිසිදු මොඩියුලයක් ස්වයංක්‍රීයව ආනයනය නොකිරීමයි.
Nikratio

විට සියලු [foo තීරුව] අඩංගු test.py ගොනුවේ භාවිතා කරනවා නම්: * පැකේජය සඳහා ආනයන, එසේ නම්, foo හා බාර් test.py දේශීය නාමඅවකාශයෙහි හෝ foo සහ පොලූ ම නාමඅවකාශයෙහි ආනයනය ලබා ගන්නේ කෙසේද?
විචල්‍යය

88

පයිඩොක් පෙන්වන දේ ද එය වෙනස් කරයි:

module1.py

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

module2.py

__all__ = ['a', 'b']

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

y pydoc module1

මොඩියුලය 1 සඳහා උදව්:

නාමය
    මොඩියුලය 1

ගොනුව
    module1.py

DATA 
    a = 'A'
     b = 'B'
     c = 'C'

y pydoc module 2

මොඩියුලය 2 සඳහා උදව්:

නාමය
    මොඩියුලය 2

ගොනුව
    module2.py

දත්ත 
    __all__ = ['a', 'b']
     a = 'A'
     b = 'B'

මගේ __all__සියලු මොඩියුලවල මෙන්ම අභ්‍යන්තර තොරතුරු අවධාරනය කරමින් මම ප්‍රකාශ කරමි, සජීවී පරිවර්තක සැසි වලදී ඔබ මීට පෙර භාවිතා නොකළ දේවල් භාවිතා කරන විට මේවා සැබවින්ම උපකාරී වේ.


58

__all__අභිරුචිකරණය *කරයිfrom <module> import *

__all__අභිරුචිකරණය *කරයිfrom <package> import *


මොඩියුලය යනු .pyආනයනය කිරීමට අදහස් ගොනු.

පැකේජය සමඟ නාමාවලියකි __init__.pyගොනුව. පැකේජයක සාමාන්‍යයෙන් මොඩියුල අඩංගු වේ.


මොඩියුල

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

__all__ = ['swiss', 'cheddar']

swiss = 4.99
cheddar = 3.99
gouda = 10.99

__all__මොඩියුලයක “පොදු” ලක්ෂණ දැන ගැනීමට මිනිසුන්ට ඉඩ දෙයි . [ AaronHall ] එසේම, pydoc ඒවා හඳුනා ගනී. [ Ong ලෝන්ග්පොක් ]

සිට මොඩියුලය ආනයන *

දේශීය නාම අවකාශයට ගෙන එන්නේ කෙසේද swissසහ cheddarගෙන එන්නේ කෙසේදැයි බලන්න , නමුත් එසේ නොවේ gouda:

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

එසේ __all__නොවුවහොත්, ඕනෑම සංකේතයක් (එය අවධාරනයකින් ආරම්භ නොවේ) ලබා ගත හැකිව තිබුණි.


නැති ආනයන *වලට බලපෑමක් නැත__all__


ආයාත මොඩියුලය

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

සිට මොඩියුලය ආනයන නම්

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

ආනයන මොඩියුලය ලෙස localname

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

පැකේජ

තුළ __init__.pyඇති වන ගොනු පැකේජය __all__ රාජ්ය මොඩියුල හෝ වෙනත් වස්තූන් නම් සහිත නූල් ලැයිස්තුවකි. එම අංග ආදේශක කාඩ්පත් ආනයනය සඳහා ලබා ගත හැකිය. මොඩියුල මෙන්, පැකේජයෙන් ආදේශක ආනයනය __all__කරන *විට අභිරුචිකරණය කරයි . [ Ar මාටින්ස්ටෙට්නර් ]

පයිතන් MySQL සම්බන්ධකයේ උපුටා ගැනීමක් මෙන්න __init__.py:

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

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

    # Error handling
    'Error', 'Warning',

    ...etc...

    ]

පෙරනිමි නඩුව, පැකේජයක් නොමැති තරු ලකුණු__all__ කිරීම සංකීර්ණ වේ, මන්ද පැහැදිලි හැසිරීම මිල අධික වනු ඇත: පැකේජයේ ඇති සියලුම මොඩියුලයන් සෙවීමට ගොනු පද්ධතිය භාවිතා කිරීම. ඒ වෙනුවට, මගේ ලියකියවිලි කියවීමේදී __init__.pyආනයනය කරනු ලබන්නේ අර්ථ දක්වා ඇති වස්තූන් පමණි :

නම් __all__අර්ථ දක්වා නැත, මෙම ප්රකාශය from sound.effects import *කරන්නේ නෑ පැකේජය සියලු submodules ආනයනය sound.effectsවත්මන් නාමඅවකාශයෙහි බවට; එමඟින් පැකේජය sound.effectsආනයනය කර ඇති බව සහතික කරයි (සමහරවිට ආරම්භක කේතයක් ක්‍රියාත්මක විය හැක __init__.py) පසුව පැකේජයේ අර්ථ දක්වා ඇති ඕනෑම නම් ආනයනය කරයි. අර්ථ දක්වා ඇති ඕනෑම නම් (සහ පැහැදිලිව පටවා ඇති උප මොඩියුල) මෙයට ඇතුළත් වේ __init__.py. පෙර ආනයන ප්‍රකාශ මගින් පැහැදිලිව පටවා ඇති පැකේජයේ ඕනෑම උප මොඩියුලයක් ද එයට ඇතුළත් ය.


වයිල්ඩ්කාඩ් ආනයනය ... ඒවා පා readers කයන් සහ බොහෝ ස්වයංක්‍රීය මෙවලම් [ව්‍යාකූල කරන බැවින්] වළක්වා ගත යුතුය.

[ PEP 8 , oolToolmakerSteve]


2
මම ඇත්තටම මේ පිළිතුරට සමාන, නමුත් මම පෙර සැකසුම් හැසිරීම සඳහා මොකක්ද පිළිබඳ තොරතුරු, අතුරුදහන් කරනවා from <package> import *තොරව __all__දී __init__.pyඇති බව ෙම ල ඕනෑම ආනයනය නොවේ .
radzak

ස්තූතියි at ජාතිමීර්, අත්හදා බැලීම් නොකර මට හැකි උපරිමයෙන් මම පැහැදිලි කළෙමි. මම පාහේ (අ පැකේජයක් සඳහා සියලු දෙනා නොමැතිව තරු ලකුණ) එම ලෙස හැසිරෙන මෙම නඩුව කියන්න අවශ්ය නම් __init__.pyමොඩියුල මොඩියුල විය . නමුත් එය නිවැරදි යැයි මට විශ්වාස නැත, හෝ විශේෂයෙන් අවධාරනය කරන ලද උපසර්ග සහිත වස්තූන් බැහැර කර තිබේ නම්. එසේම, මම වඩාත් පැහැදිලිව මොඩියුල සහ ඇසුරුම්වල කොටස් වෙන් කළෙමි. ඔබේ සිතුවිලි?
බොබ් ස්ටයින්

50

සිට (නිල නොවන) Python විමර්ශන විකිපීඩියා, නිදහස් විශ්වකෝෂය :

මොඩියුලයක් මගින් අර්ථ දක්වා ඇති පොදු නම් තීරණය කරනු ලබන්නේ විචල්‍යයක් සඳහා මොඩියුලයේ නාම අවකාශය පරීක්ෂා කිරීමෙනි __all__; නිර්වචනය කර ඇත්නම්, එය එම මොඩියුලය විසින් නිර්වචනය කරන ලද හෝ ආනයනය කරන ලද නම් වන නූල් අනුක්‍රමයක් විය යුතුය. දක්වා ඇති නම් __all__සියල්ලම පොදු ලෙස සලකනු ලබන අතර ඒවා පැවතිය යුතුය. __all__නිර්වචනය කර නොමැති නම් , පොදු නම් කට්ටලයට මොඩියුලයේ නාම අවකාශයේ ඇති සියලුම නම් ඇතුළත් වන අතර එය අවධාරනය කරන අක්ෂරයකින් ("_") ආරම්භ නොවේ. __all__සම්පූර්ණ පොදු API අඩංගු විය යුතුය. ඒපීඅයි හි කොටසක් නොවන (මොඩියුලය තුළ ආනයනය කර භාවිතා කරන ලද පුස්තකාල මොඩියුල වැනි) අහම්බෙන් අපනයනය කිරීමෙන් වළක්වා ගැනීමට අදහස් කෙරේ.


ලැයිස්තුගත සබැඳිය මිය ගොස් ඇත. නමුත් vdocuments.net/… සහ මෙහි පෙළ වාචික වචන හමු විය : dokumen.tips/documents/reference-567bab8d6118a.html
JayRizzo

8

__all__පයිතන් මොඩියුලයක පොදු API ලේඛනගත කිරීමට භාවිතා කරයි. එය විකල්පයක් වුවද __all__භාවිතා කළ යුතුය.

පයිතන් භාෂා යොමුවෙහි අදාළ උපුටා ගැනීම මෙන්න :

මොඩියුලයක් මගින් අර්ථ දක්වා ඇති පොදු නම් තීරණය කරනු ලබන්නේ විචල්‍යයක් සඳහා මොඩියුලයේ නාම අවකාශය පරීක්ෂා කිරීමෙනි __all__; නිර්වචනය කර ඇත්නම්, එය එම මොඩියුලය විසින් නිර්වචනය කරන ලද හෝ ආනයනය කරන ලද නම් වන නූල් අනුක්‍රමයක් විය යුතුය. දක්වා ඇති නම් __all__සියල්ලම පොදු ලෙස සලකනු ලබන අතර ඒවා පැවතිය යුතුය. __all__නිර්වචනය කර නොමැති නම් , පොදු නම් කට්ටලයට මොඩියුලයේ නාම අවකාශයේ ඇති සියලුම නම් ඇතුළත් වන අතර එය අවධාරනය කරන අක්‍ෂරයකින් ('_') ආරම්භ නොවේ. __all__සම්පූර්ණ පොදු API අඩංගු විය යුතුය. ඒපීඅයි හි කොටසක් නොවන (මොඩියුලය තුළ ආනයනය කර භාවිතා කරන ලද පුස්තකාල මොඩියුල වැනි) අහම්බෙන් අපනයනය කිරීමෙන් වළක්වා ගැනීමට අදහස් කෙරේ.

PEP 8 සමාන වචන භාවිතා කරයි, නමුත් ආනයනික නම් නොමැති විට පොදු API හි කොටසක් නොවන බව පැහැදිලි කරයි __all__:

ස්වයං පරීක්‍ෂණයට වඩා හොඳ සහය දැක්වීම සඳහා, මොඩියුලයන් ඔවුන්ගේ පොදු API හි ඇති __all__ගුණාංගය පැහැදිලිවම ප්‍රකාශ කළ යුතුය . කිරීම __all__මෙම මොඩියුලය කිසිදු මහජන API ඇති බව හිස් ලැයිස්තුවට බවයි.

[...]

ආනයනය කළ නම් සැමවිටම ක්‍රියාත්මක කිරීමේ විස්තරයක් ලෙස සැලකිය යුතුය. වෙනත් මොඩියුලයන් ආනයනය කරන ලද නම් වලට වක්‍රව ප්‍රවේශ වීම මත රඳා නොසිටිය යුතුය, ඒවා අඩංගු මොඩියුලයේ ඒපීඅයි හි පැහැදිලිව ලේඛනගත කර ඇති කොටසක් os.pathහෝ උප __init__මොඩියුල වලින් ක්‍රියාකාරීත්වය හෙළි කරන පැකේජයක මොඩියුලයක් වේ.

තවද, වෙනත් පිළිතුරු වල පෙන්වා ඇති __all__පරිදි, පැකේජ සඳහා ආදේශක කාඩ් ආනයනය සක්‍රීය කිරීම සඳහා භාවිතා කරයි :

ආනයන ප්‍රකාශය පහත දැක්වෙන සම්මුතිය භාවිතා කරයි: පැකේජයක __init__.pyකේතයක් නම් කරන ලද ලැයිස්තුවක් අර්ථ දක්වන්නේ නම් __all__, එය from package import *හමු වූ විට ආනයනය කළ යුතු මොඩියුල නාම ලැයිස්තුවක් ලෙස සලකනු ලැබේ.


8

කෙටි පිළිතුර

__all__from <module> import *ප්‍රකාශ වලට බලපායි .

දිගු පිළිතුර

මෙම උදාහරණය සලකා බලන්න:

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

තුළ foo/__init__.py:

  • (ව්‍යංග) අප අර්ථ දක්වන්නේ __all__නැත්නම්, from foo import *ආනයනය කරනුයේ අර්ථ දක්වා ඇති නම් පමණි foo/__init__.py.

  • (පැහැදිලි) අපි නිර්වචනය නම් __all__ = [], එසේ නම් from foo import *කිසිම දෙයක් ආනයනය කරයි.

  • (පැහැදිලි) අප අර්ථ දක්වන්නේ නම් __all__ = [ <name1>, ... ], from foo import *එම නම් පමණක් ආනයනය කරනු ඇත.

ව්‍යංග නඩුවේදී, පයිතන් ආරම්භ වන නම් ආනයනය නොකරන බව සලකන්න _. කෙසේ වෙතත්, ඔබට එවැනි නම් ආනයනය කිරීමට බල කළ හැකිය __all__.

ඔබට මෙහි පයිතන් ලේඛනය නැරඹිය හැකිය .


6

__all__from foo import *ක්‍රියා කරන ආකාරය කෙරෙහි බලපායි .

මොඩියුල ශරීරයක් තුළ ඇති කේතය (නමුත් ශ්‍රිතයක හෝ පන්තියක ශරීරයේ නොවේ *) fromප්‍රකාශයක තරු ලකුණු ( ) භාවිතා කළ හැකිය :

from foo import *

*මොඩියුලයේ සියලුම ගුණාංග foo(අවධාරනයෙන් ආරම්භ වන ඒවා හැර) ආයාත කිරීමේ මොඩියුලයේ ගෝලීය විචල්‍යයන් ලෙස බැඳී ඇති ඉල්ලීම් . fooගුණාංගයක් ඇති විට __all__, ගුණාංගයේ වටිනාකම යනු මෙම වර්ගයේ fromප්‍රකාශයන්ට බැඳී ඇති නම් ලැයිස්තුවයි .

නම් fooකියන්නේ පැකේජය සහ එහි __init__.pyඅර්ථ දක්වන්නේ නම් ලැයිස්තුව __all__, එය විට ආනයනය කළ යුතු බව submodule නාම ලැයිස්තුවක් විය ගැනීමට කටයුතු කරනු ලැබේ from foo import *මුහුණ වේ. __all__අර්ථ දක්වා නොමැති නම් , ප්‍රකාශය from foo import *ඇසුරුමේ අර්ථ දක්වා ඇති ඕනෑම දෙයක් ආනයනය කරයි. අර්ථ දක්වා ඇති ඕනෑම නම් (සහ පැහැදිලිව පටවා ඇති උප මොඩියුල) මෙයට ඇතුළත් වේ __init__.py.

__all__ලැයිස්තුවක් විය යුතු නැති බව සලකන්න . importප්‍රකාශයේ ඇති ප්‍රලේඛනයට අනුව , නිර්වචනය කර ඇත්නම්, මොඩියුලය විසින් නිර්වචනය කරන ලද හෝ ආනයනය කරන ලද නම් වන නූල් අනුක්‍රමයක්__all__ විය යුතුය . එමනිසා ඔබට යම් මතකයක් සහ CPU චක්‍රයක් ඉතිරි කර ගැනීමට ටුපල් එකක් භාවිතා කළ හැකිය . මොඩියුලය තනි පොදු නමක් අර්ථ දක්වන්නේ නම් කොමාව අමතක නොකරන්න:

__all__ = ('some_name',)

මෙයද බලන්න ඇයි "ආනයන *" නරක ද?


1

මෙය මෙහි PEP8 හි අර්ථ දක්වා ඇත :

ගෝලීය විචල්‍ය නම්

(මෙම විචල්‍යයන් එක් මොඩියුලයක් තුළ පමණක් භාවිතා කිරීමට අදහස් කරයි යැයි අපි ප්‍රාර්ථනා කරමු.) සම්මුතීන් ශ්‍රිත සඳහා සමාන වේ.

භාවිතා කිරීම සඳහා නිර්මාණය කර ඇති මොඩියුලයන් ගෝලීය අපනයනය වැළැක්වීම සඳහා යාන්ත්‍රණය from M import *භාවිතා කළ යුතුය __all__, නැතහොත් එවැනි ගෝලීයයන් යටි ඉරි සහිත උපසර්ගයක් භාවිතා කිරීමේ පැරණි සම්මුතිය භාවිතා කළ යුතුය (මෙම ගෝලීයයන් “පොදු නොවන මොඩියුලය” බව දැක්වීමට ඔබට අවශ්‍ය විය හැකිය).

PEP8 ප්‍රධාන පයිතන් බෙදාහැරීමේ සම්මත පුස්තකාලයෙන් සමන්විත පයිතන් කේතය සඳහා කේතීකරණ සම්මුතීන් සපයයි. ඔබ මෙය වැඩි වැඩියෙන් අනුගමනය කරන තරමට, ඔබ මුල් අභිප්‍රාය වෙත සමීප වේ.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.