Прежде всего, если вам нужен настоящий root регистратор, позвоните getLogger()
без каких-либо аргументов.
Для получения дополнительных сведений о том, что будет описано ниже, см. Документацию о том, как модуль logging
устанавливает иерархию.
Произошло то, что вы вызвали getLogger(__name__)
в parent.py
, который автоматически получает указанный c логгер с именем, которому назначен на __name__
, а не на сам логгер root (поскольку вы непосредственно выполнили файл parent.py
, он становится модулем __main__
). Что касается child.py
, он был импортирован как child
, поэтому __name__
был установлен как child
, таким образом, он действительно был на один уровень ниже от регистратора "root" и не имеет никакого другого родителя.
Поскольку модуль logging
использует точку (.
) в качестве разделителя, это приводит к тому, что вы, возможно, прочитали некоторую рекомендацию по использованию getLogger(__name__)
как способа получить общего родителя для детские регистраторы. Можно отметить, что в Python разделитель пространства имен также .
, так что __name__
, который автоматически доступен для любого данного модуля, будет каноническим именем импорта.
Для иллюстрации на примере, учитывая следующую структуру пакета примера:
.
├── example
│ ├── __init__.py
│ ├── lib.py
│ ├── main.py
│ └── submodule
│ ├── __init__.py
│ ├── demo1.py
│ └── demo2.py
└── setup.py
Внутри example/__init__.py
, регистратор может быть настроен как таковой (заимствовать часть вашего примера):
import logging
import sys
logger = logging.getLogger(__name__)
handler = logging.StreamHandler(sys.stdout)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
Это будет в факт установки «родительского» регистратора для всех регистраторов с префиксом 'example.'
, так как __name__
будет преобразовываться в example
, когда другой модуль делает import example
.
. Кстати, это также означает, что другие модули, такие как example.main
и даже example.submodule.demo1
(которые эти соответствующие модули также приобретут своими регистраторами с тем же кодом, getLogger(__name__)
), теперь фактически получат преимущества от обработчика и уровня, которые были установлены их относительными root регистратор сделан внутри example
модуля. Аналогично, внутри example/submodule/__init__.py
этот модуль может получить общего родителя для всего регистратора с префиксом 'example.submodule.'
, просто присваивая результат getLogger(__name__)
переменной и используя его.