Зачем импортировать * а потом ТТК?
Я понимаю, что стандартная настройка для программы tkinter начинается так:
from tkinter import *
from tkinter import ttk
Я понимаю, что tkinter-это пакет, но если я уже импортировал все с *
, почему мне все еще нужно импортировать ttk
? Почему я получаю ошибку, если я вынимаю вторую строку и пытаюсь ссылаться ttk
?
4 ответов
когда вы from some_package import *
, python импортирует все, что этот пакет выбирает для экспорта. То, что он выбирает для экспорта, может быть подмножеством того, что фактически хранится в папке пакета. Почему так? Нет никакой особой причины, это просто то, как автор пакета решил сделать что-то.
эта информация о том, что экспортировать, определяется в __init__.py
файл, который находится внутри пакета (в этом случае,tkinter/init.py). Если вы посмотрите на этот файл, вы обратите внимание, что он не импортирует сам ttk, поэтому ttk не будет экспортироваться и поэтому не может быть импортирован с импортом подстановочных знаков.
опять же, нет никакой особой причины, кроме того, как авторы tkinter и ttk решили делать вещи.
для получения дополнительной информации о механике упаковки см. часть упаковки учебника python (https://docs.python.org/3/tutorial/modules.html#packages)
лучший способ импорта tkinter
вы можете подумать, что это стандарт, потому что многие учебники делают это таким образом, но это, как правило, плохая практика. Лучший способ, ИМО, - дать библиотеке tkinter явное имя:
# python 3.x
import tkinter as tk
from tkinter import ttk
# python 2.x
import Tkinter as tk
import ttk
это сделает ваш код намного легче читать, потому что вы должны явно указать, какой инструментарий вы используете:
b1 = tk.Button(...) # uses a standard tk button
b2 = ttk.Button(...) # uses a ttk button
Я не могу придумать никакой веской причины делать это по-другому. Выполнение глобального импорта экономит вам пару байтов каждый раз, когда вы вызываете функция tkinter, но за счет ясности. Кроме того, это усиливает плохую практику, которая может кровоточить в том, как вы используете другие библиотеки.
реальная власть, ИМО, это PEP8, что говорит по этому поводу:
импорта подстановочных знаков (из import *) следует избегать, поскольку они делают неясным, какие имена присутствуют в пространстве имен, запутывая как читателей, так и многие автоматизированные инструменты. Существует один оправданный вариант использования для импорта подстановочных знаков, который должен переиздать внутренний интерфейс как часть публичного API (например, перезапись чистой реализации Python интерфейса с определениями из дополнительного модуля ускорителя и точно, какие определения будут перезаписаны, заранее не известно).
, потому что tkinter/__init__.py
не import ttk
, so ttk
не входит в from tkinter import *
.
в двух других ответах здесь не удалось указать, что ttk не импортируется, потому что это подмодуль в модуле tkinter, фактически модуль сам по себе.
поэтому при импорте tkinter вы получаете все части, которые непосредственно принадлежат tkinter
но ttk не принадлежит напрямую и поэтому должен быть импортирован явно.
однако Брайан Оукли делает хороший момент, что импорт всего из модуля в локальное пространство имен (как и многие новички) может привести к большим проблемам позже, когда вы начнете использовать дополнительные модули. это связано с тем, что некоторые из этих модулей могут иметь общие имена функций, даже если сами функции могут делать совершенно разные вещи.
это всегда лучше для больших модулей делаем так:
import module as mod
или
import module
а затем ссылаться на функции, принадлежащие пространству имен modules:
module.function()
это дает вам больше контроля над тем, что вы делаете, и делает его более четким позже, к чему на самом деле принадлежала эта функция.
кратко: from tkinter import *
импорт из файла/пакета tkinter
но это не означает, что он будет импортировать из файла / пакета tkinter.ttk