Зачем импортировать * а потом ТТК?

Я понимаю, что стандартная настройка для программы 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