Bug or my misunderstanding? - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Bug or my misunderstanding? (/thread-7333.html) |
Bug or my misunderstanding? - MrSteveVee - Jan-04-2018 Hi all, I am trying to get to grips with Python using Visual Studio 2017 on Windows 10 and have a problem that may be a bug in VS or my misunderstanding of an import concept. If I use the following code (snippet) on the line "name =" I get the error that tkinter does not contain filedialog import tkinter as TK .... name = TK.filedialog.askopenfilename() However, if I add one extra line as follows it now works fine, but I cannot see how the 2nd line added can effect the "name = " line that failed the first test import tkinter as TK from tkinter.filedialog import askopenfilename .... name = TK.filedialog.askopenfilename() Is this a problem with visual studio and Python or have a misunderstood the import directive Thanks in advance RE: Bug or my misunderstanding? - metulburr - Jan-04-2018 its not a bug. Its the way tkinter is packaged. When you just import tkinter, python looks for a tkinter.py file or a tkinter directory. If it is a directory, it looks for a __init__.py file in that directory. The __init__.py file then is put in your namespace. If you grep the class headers of that init file, you will see familiar class names. metulburr@ubuntu:/usr/lib/python3.5/tkinter$ cat __init__.py | grep class Tkinter provides classes which allow the display, positioning and class Event: using bind, bind_all, bind_class, or tag_bind, the callback is class Variable: Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations return self.__class__.__name__ == other.__class__.__name__ \ class StringVar(Variable): class IntVar(Variable): class DoubleVar(Variable): class BooleanVar(Variable): class Misc: """Internal class. Base class which defines methods common for interior widgets.""" def option_get(self, name, className): return self.tk.call('option', 'get', self._w, name, className) def winfo_class(self): """Return window class name of this widget.""" return self.tk.call('winfo', 'class', self._w) def bind_class(self, className, sequence=None, func=None, add=None): return self._bind(('bind', className), sequence, func, add, 0) def unbind_class(self, className, sequence): self.tk.call('bind', className , sequence, '') self.__class__.__module__, self.__class__.__qualname__, self._w) class CallWrapper: """Internal class. Stores function to call when some user class XView: """Mix-in class for querying and changing the horizontal position class YView: """Mix-in class for querying and changing the vertical position class Wm: class Tk(Misc, Wm): def __init__(self, screenName=None, baseName=None, className='Tk', is the name of the widget class.""" self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) self.readprofile(baseName, className) def readprofile(self, baseName, className): class_tcl = os.path.join(home, '.%s.tcl' % className) class_py = os.path.join(home, '.%s.py' % className) if os.path.isfile(class_tcl): self.tk.call('source', class_tcl) if os.path.isfile(class_py): exec(open(class_py).read(), dir) # Ideally, the classes Pack, Place and Grid disappear, the # pack/place/grid methods are defined on the Widget class, and # Pack, Place or Grid class, so I leave them intact -- but only as # the Misc class (which now incorporates all methods common between # copied into the Pack, Place or Grid class. def Tcl(screenName=None, baseName=None, className='Tk', useTk=0): return Tk(screenName, baseName, className, useTk) class Pack: Base class to use the methods pack_* in every widget.""" class Place: Base class to use the methods place_* in every widget.""" class Grid: Base class to use the methods grid_* in every widget.""" class BaseWidget(Misc): """Internal class.""" classes = [(k, v) for k, v in cnf.items() if isinstance(k, type)] for k, v in classes: for k, v in classes: class Widget(BaseWidget, Pack, Place, Grid): """Internal class. Base class for a widget which can be positioned with the geometry managers class Toplevel(BaseWidget, Wm): Valid resource names: background, bd, bg, borderwidth, class, for wmkey in ['screen', 'class_', 'class', 'visual', class Button(Widget): class Canvas(Widget, XView, YView): class Checkbutton(Widget): class Entry(Widget, XView): class Frame(Widget): Valid resource names: background, bd, bg, borderwidth, class, if 'class_' in cnf: extra = ('-class', cnf['class_']) del cnf['class_'] elif 'class' in cnf: extra = ('-class', cnf['class']) del cnf['class'] class Label(Widget): class Listbox(Widget, XView, YView): class Menu(Widget): class Menubutton(Widget): class Message(Widget): class Radiobutton(Widget): class Scale(Widget): class Scrollbar(Widget): class Text(Widget, XView, YView): class _setit: """Internal class. It wraps the command in the widget OptionMenu.""" class OptionMenu(Menubutton): class Image: """Base class for images.""" class PhotoImage(Image): class BitmapImage(Image): class Spinbox(Widget, XView): class LabelFrame(Widget): background, class, colormap, container, class PanedWindow(Widget):These are the most used. However not everything is in there. As you can see from metulburr@ubuntu:/usr/lib/python3.5/tkinter$ ls colorchooser.py dialog.py font.py messagebox.py simpledialog.py commondialog.py dnd.py __init__.py __pycache__ tix.py constants.py filedialog.py __main__.py scrolledtext.py ttk.pythe only one of these that are imported into __init__.py file are the constants file here metulburr@ubuntu:/usr/lib/python3.5/tkinter$ cat __init__.py | grep import import tkinter from tkinter.constants import * import sys import _tkinter from tkinter.constants import * import re import warnings import os import os exec('from tkinter import *', dir) import traceback import warningseverything else will need a separate import. You can remedy the fact of importing each sub-module individually by importing all with star imports, but that is not a good idea. Instead of from tkinter.filedialog import askopenfilenameyou can just do from tkinter import filedialogthen if you need more dialogs in that module you dont need to import each one. RE: Bug or my misunderstanding? - MrSteveVee - Jan-04-2018 Many thanks for such a detailed reply, it has solved my problem and helped a lot in understanding how import works |