Вот что я узнал…

И так, продолжаю изучать Python и узнавать что-то новое. Дабы закрепить свои знания, делаю пометки в виде постов. Что сегодня я узнал…

Когда начал изучать Python, все курсы и уроки, рассказывающие про модули умалчивали про то, что можно управлять тем, что импортируется из модулей. И только недавно узнал про ключевое слово __all__.

$ cat foo.py
def a(): print("function a()")
def b(): print("function b()")
$ cat app.py
from foo import *
a()
b()

Все отработает, но если мы сделаем так:

$ cat foo.py
def a(): print("function a()")
def b(): print("function b()")
__all__ = ["a"]

то

from foo import *

b()
NameError: name 'b' is not defined

Если задать None, то вообще не импортируется ничего:

__all__ = None

И вроде бы круто, можно управлять. Но, как оказалось, поведение его не совсем то, какое я ожидал. Оказывается что этот механизм не защищает от прямых обращений вида:

from foo import a, b

Такой импорт игнорирует __all__ и это было для меня не очевидно, но это описано в документации и так задумано, так что все ок.


Собственно вот что сегодня я узнал…