Path: csiph.com!usenet.pasdenom.info!aioe.org!news.stack.nl!newsfeed.xs4all.nl!newsfeed3a.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'elif': 0.05; 'root': 0.05; '"""': 0.07; 'attribute': 0.07; 'class,': 0.07; 'element': 0.07; 'lines,': 0.07; 'none,': 0.07; 'none:': 0.07; "subject:' ": 0.07; 'tkinter': 0.07; 'arguments': 0.09; 'attributes': 0.09; 'function,': 0.09; 'method,': 0.09; 'mixed': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'wrapper': 0.09; '{},': 0.09; 'python': 0.11; 'def': 0.12; 'gui': 0.12; 'ast': 0.16; 'cmd,': 0.16; 'command:': 0.16; 'frame,': 0.16; 'keys.': 0.16; 'kw:': 0.16; 'received:80.91.229.3': 0.16; 'received:dip0.t-ipconnect.de': 0.16; 'received:plane.gmane.org': 0.16; 'received:t-ipconnect.de': 0.16; 'root:': 0.16; 'str):': 0.16; 'subject:object': 0.16; 'subject:where': 0.16; 'tcl': 0.16; 'typeerror:': 0.16; 'wrote:': 0.18; 'skip:p 40': 0.19; 'written': 0.21; '>>>': 0.22; 'code,': 0.22; 'import': 0.22; 'header:User- Agent:1': 0.23; 'convenient': 0.24; 'module,': 0.24; 'skip:{ 20': 0.24; 'holds': 0.26; 'skip:" 30': 0.26; 'required.': 0.27; 'values': 0.27; 'header:X-Complaints-To:1': 0.27; 'point': 0.28; 'wondering': 0.29; 'skip:p 30': 0.29; 'specified': 0.30; 'code': 0.31; "skip:' 10": 0.31; '"",': 0.31; '>>>>': 0.31; 'inspect': 0.31; 'file': 0.32; 'probably': 0.32; '(most': 0.33; 'actual': 0.34; 'skip:_ 10': 0.34; 'skip:s 30': 0.35; 'no,': 0.35; 'there': 0.35; 'keyword': 0.36; 'method': 0.36; 'possible': 0.36; 'list.': 0.37; 'skip:o 20': 0.38; 'to:addr:python-list': 0.38; 'recent': 0.39; 'to:addr:python.org': 0.39; 'received:org': 0.40; 'color': 0.61; 'new': 0.61; 'reached': 0.63; 'choose': 0.64; 'more': 0.64; 'here': 0.66 X-Injected-Via-Gmane: http://gmane.org/ To: python-list@python.org From: Peter Otten <__peter__@web.de> Subject: Re: I dont understand root['bg'] = 'red' where root is a tkinter.Tk object Date: Mon, 17 Nov 2014 15:14:20 +0100 Organization: None References: <5469f8d3$0$5132$426a74cc@news.free.fr> Mime-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7Bit X-Gmane-NNTP-Posting-Host: p57bd8622.dip0.t-ipconnect.de User-Agent: KNode/4.13.3 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 94 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1416233676 news.xs4all.nl 2905 [2001:888:2000:d::a6]:34434 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:80976 ast wrote: > Hello, > > import tkinter > root = tkinter.Tk() > > Let's see all attributes of root: > >>>> root.__dict__ > {'master': None, 'children': {}, '_tclCommands': ['tkerror', 'exit', > {'13825848destroy'], 'tk': > , '_tkloaded': 1} > > Now we change the background color using following command: >>>> root['bg'] = 'red' > > I am wondering what 'bg' is for object root. Is it an attribute ? > >>>> root.__dict__ > {'master': None, 'children': {}, '_tclCommands': ['tkerror', 'exit', > {'13825848destroy'], 'tk': > , '_tkloaded': 1} > > No, 'bg' is not in root attribute's list. So what is it ? Let's drill down a bit: >>> import tkinter, inspect >>> print(inspect.getsource(tkinter.Tk.__setitem__)) def __setitem__(self, key, value): self.configure({key: value}) >>> print(inspect.getsource(tkinter.Tk.configure)) def configure(self, cnf=None, **kw): """Configure resources of a widget. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method keys. """ return self._configure('configure', cnf, kw) >>> print(inspect.getsource(tkinter.Tk._configure)) def _configure(self, cmd, cnf, kw): """Internal function.""" if kw: cnf = _cnfmerge((cnf, kw)) elif cnf: cnf = _cnfmerge(cnf) if cnf is None: return self._getconfigure(_flatten((self._w, cmd))) if isinstance(cnf, str): return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf))) self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) >>> print(inspect.getsource(root.tk.call)) Traceback (most recent call last): File "", line 1, in File "/usr/lib/python3.4/inspect.py", line 830, in getsource lines, lnum = getsourcelines(object) File "/usr/lib/python3.4/inspect.py", line 819, in getsourcelines lines, lnum = findsource(object) File "/usr/lib/python3.4/inspect.py", line 655, in findsource file = getfile(object) File "/usr/lib/python3.4/inspect.py", line 536, in getfile 'function, traceback, frame, or code object'.format(object)) TypeError: is not a module, class, method, function, traceback, frame, or code object OK, we've reached C code, from here more traditional methods of code inspection are required. tkinter is a wrapper for a GUI written in tcl/tk. For every GUI element in tkinter there is a corresponding tcl object that holds the actual bg data. It's just that at some point in the development of tkinter someone thought that widget["bg"] = "red" is more convenient than widget.configure(bg="red") While it would have been possible to choose widget.bg = "red" that would have mixed the tcl and python namespaces. When the tcl object acquires new attributes hilarity ensues... (I probably would have chosen widget.gui.bg = "red")