[FAQTS] Python Knowledge Base Update -- July 17th, 2000

Fiona Czuczman fiona at sitegnome.com
Mon Jul 17 00:52:37 EDT 2000


Hi Guys,

Below are the latest entries to be entered into http://python.faqts.com

cheers,

Fiona Czuczman

Including:

- I'm writing a script that will act as a GUI interface to another 
script, and I want to have file browsing ability. How do I call this in 
Tkinter?
- Searching code for parsing mail headers encoded according to  RFC 2047 
(Message Header Extensions for Non-ASCII Text).
- Is there a way how I can identify the operating system my Python 
script is running on (e.g., Linux, Windows, Mac, ...)?
- How does python invoke external C function?
- How do I go about getting my dynamic IP address?
- How does the statement 'global' work?


## Unanswered Questions ########################################


-------------------------------------------------------------
can i run a script in an already running interpreter to hook a gui to a server process
http://www.faqts.com/knowledge-base/view.phtml/aid/4761
-------------------------------------------------------------
Slimy



## New Entries #################################################


-------------------------------------------------------------
I'm writing a script that will act as a GUI interface to another script, and I want to have file browsing ability. How do I call this in Tkinter?
http://www.faqts.com/knowledge-base/view.phtml/aid/4768
-------------------------------------------------------------
Fiona Czuczman
John Grayson

This is not really a Tkinter issue, since you can fire up a file browser 
window from a simple Python program. However, it may introduce some 
special problems if you're doing it from a GUI. Therefore, here is some 
sample code to illustrate how to do this for Windows and Solaris 
platforms. You would have to adjust for other platforms. Note that if 
you're doing this just for Unix, that you don't need to thread: you can 
just fire off the command in the background...

from Tkinter import *
from tkSimpleDialog import *
import sys, os, thread


class App:
    def __init__(self, master):
        self.master = master
        Label(master, text='Browsing:').pack(side=LEFT,
                                             padx=4, pady=15)
        self.entry  = StringVar()
        Entry(master, width=50, bg='gray', textvariable=self.entry,
              state=DISABLED).pack(side=LEFT, padx=15, pady=15)
        Button(master, text='Browse...',
               command=self.browse).pack(side=BOTTOM)

    def browse(self):
        path  = askstring("Browse", "Enter directory")
        self.entry.set(path)

        browser = Browse(folder=path)

class Browse:
    def __init__(self, folder='.'):
        if sys.platform == 'win32':
            cmd = 'Explorer %s' % folder
        else:
            cmd = 'dtfile -folder %s' % folder
        thread.start_new_thread(self.doIt, (cmd,))

    def doIt(self, where):
        os.system(where)


root = Tk()
display = App(root)
root.mainloop()

Hope this helps to get you started.

BTW: Chapter 18 of Python and Tkinter Programming covers
handling asynchronous events and things that block the
mainloop...


-------------------------------------------------------------
Searching code for parsing mail headers encoded according to  RFC 2047 (Message Header Extensions for Non-ASCII Text).
http://www.faqts.com/knowledge-base/view.phtml/aid/4772
-------------------------------------------------------------
Fiona Czuczman
François Pinard

I needed this soon after learning Python (so this is part of my first 
Python lines, I would probably write something simpler today :-) and 
quickly wrote what appears below.  However, I found out after the fact 
that the Python library had something already.  See 
mimify.mime_decode_header.


# Handling of RFC 2047 (previously RFC 1522) headers.

import re, string

def to_latin1(text):
    return _sub_f(r'=\?ISO-8859-1\?Q\?([^?]*)\?=', re.I, _replace1, 
text)

def _replace1(match):
    return _sub_f('=([0-9A-F][0-9A-F])', re.I, _replace2,
                  re.sub('_', ' ', match.group(1)))

def _replace2(match):
    return chr(string.atoi(match.group(1), 16))

def _sub_f(pattern, flags, function, text):
    matcher = re.compile(pattern, flags).search
    position = 0
    results = []
    while 1:
        match = matcher(text, position)
        if not match:
            results.append(text[position:])
            return string.joinfields(results, '')
        results.append(text[position:match.start(0)])
        position = match.end(0)
        results.append(function(match))


-------------------------------------------------------------
Is there a way how I can identify the operating system my Python script is running on (e.g., Linux, Windows, Mac, ...)?
http://www.faqts.com/knowledge-base/view.phtml/aid/4773
-------------------------------------------------------------
Fiona Czuczman
Emile van Sebille, Mahogany Rush, Matthew Schinckel

Look for Marc Lemburg's platform.py, or use the standard sys.platform.

Python 1.6a2 (#1, May 14 2000, 08:15:17)  [GCC 2.8.1] on sunos5
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import sys
>>> sys.platform
'sunos5'


If it is only for compatibilty reasons, you can use os.name.

This will give you one of: ['posix', 'nt', 'dos', 'mac', 'os2', 'ce'].


-------------------------------------------------------------
How does python invoke external C function?
http://www.faqts.com/knowledge-base/view.phtml/aid/4774
-------------------------------------------------------------
Fiona Czuczman
Wolfgang Grafen

I would recommend SWIG for a first step. You don't have to learn a lot
about extension modules with SWIG. Often it is easy like this (for sun 
solaris 2.5):

swig -python -module a a.c
gcc -O02 -DSWIG -c -fpic a.c a_wrap.c \
-I/user/freepool/sparc-sun-solaris2.5.1/lib/python/python1.52/include/py
thon1.5/

ld -G a.o a_wrap.o -o a.so

Then in Python you can use it like it is.

Python 1.5.2 (#33, May 17 2000, 17:03:52)  [GCC 2.7.2] on sunos5
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import a
>>> dir(a)
['__doc__', '__file__', '__name__', 'hex2bin', 'hex2bin_char',
'hex2bin_expand']
>>>

SWIG has a very good documentation. You can build extensions for PERL
and TCL the same way

http://www.swig.org

There is also another Corba-like Package called ILU. Probably SWIG is
more easy to use while ILU might be more powerful.

ftp://ftp.parc.xerox.com/pub/ilu/ilu.html


## Edited Entries ##############################################


-------------------------------------------------------------
How do I go about getting my dynamic IP address?
Detecting own computer's IP
http://www.faqts.com/knowledge-base/view.phtml/aid/4378
-------------------------------------------------------------
Nathan Wallace, Fiona Czuczman
Hans Nowak, Snippet 188, Python Snippet Support Team

"""
Packages: networking.sockets
"""

""" detectip.py
    Detects your own IP address. No big deal on Python; more work on Delphi
    (where the code originated from :).
"""

import socket

def detectip():
    buf = socket.gethostname()
    remotehost = socket.gethostbyname(buf)
    return remotehost


if __name__ == "__main__":

    print "Your IP address is", detectip()
    raw_input()


-------------------------------------------------------------
How does the statement 'global' work?
http://www.faqts.com/knowledge-base/view.phtml/aid/2902
-------------------------------------------------------------
Fiona Czuczman
Remco Gerlich, Thomas Wouters

Answer1:

Inside functions, if you assign to a variable, it is assumed to be local 
to the function. If you want to assign to a global (module namespace) 
variable, you'll have to tell Python that it's a global first. 

ie,

x = 4
def spam():
  x = 5
spam()

Doesn't change the module's x. But

x = 4
def spam()
  global x
  x = 5
spam()

does.

If, inside a function, you only use the variable and never assign to it, 
it can't be a local variable, so Python assumes you mean a global.

This doesn't only hold for functions, but classes and methods too.

Answer2:

Python has two namespaces it uses for name lookups: the 'local' 
namespace and the 'global' namespace (you could call it the 'search 
path'.) The local namespace is the function or class you are in, the 
global namespace is the namespace of the module. If you are not in a 
function or class, the local namespace is the global namespace.

However, *assigning* to a variable does not use this search path ! 
Instead, if you assign, you always assign in the local namespace. So, 
for instance:

X = None

def FillX(x):
        X = x

would not work, because the X you assign to, is the *local* X, not the
global one. This wouldn't even generate an error, by the way. Even more
confusing is it if you read from and assign to 'X' in the same function:

X = None

def FillX(x):
        if not X:
                X = x

In Python 1.5.2, this generates a NameError:

Traceback (innermost last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 2, in FillX
NameError: X

and in Python 1.6, an UnboundLocalError:

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in FillX
UnboundLocalError: X

It generates this strange error because the 'X' name exists in the local
namespace, but at the time of the test on X, it isn't filled in yet. The
interpreter knows it should be there, but can't find it at the time of
execution.

And this is what the 'global' keyword is for. It says 'this name is 
global, *even if* it gets assigned to. You only need it when you are 
assigning to globals, not when you are mutating them (appending to 
lists, adding to dictionaries, etc.)







More information about the Python-list mailing list