Re: Trying to choose between python and java
Hamilton, William <[EMAIL PROTECTED]> wrote: >> From: Beliavsky > On May 15, 1:30 am, Anthony Irwin <[EMAIL PROTECTED]> wrote: >> >>> #5 someone said that they used to use python but stopped because the >>> language changed or made stuff depreciated (I can fully remember >>> which) and old code stopped working. Is code written today likely to >>> still work in 5+ years or do they depreciate stuff and you have to >> update? The word is "deprecated." ("Depreciated" would be a financial term, not a term of art in computer science). >> Because Python 3 will change the syntax of print to disallow >> print "Hello, world." Python 3 is an exception case because it's the only time that the BFDL has specifically and intentionally declared that backward compability was NOT a goal for that version. Essentially you can consider Python 3 to be a fork ... a departure from Python 2.x and earlier. This specific change, for example, is intended to remove a consistency wart in the language. The "print" statement in Python is a special case. It's not a normal built-in function and it's not an expression. You can start writing all your code now as: print() --- calling the statement as if it were a function. Then you're future Python 3 work would consist of simply defining a suitable function named print() (if one isn't provided or the one provided isn't suited to your needs). >> a substantial fraction of Python programs in existence, including all >> of my programs, will be broken. Draw your own conclusions. Python 3 will be a different language. It'll be similar, perhaps to the disruption between Perl 4 and Perl 5; or between Perl 5 and the proposed changes to Perl 6. Keep in mind that Java has had a number of features deprecated as well. The disruption from Java 1.x to Java2 and thence to Java5 is probably greater than the level of disruption between Python 1.x and Python 2.5.x (which as been a roughly equivalent length of time --- over a decade in both cases). > No, they'll work just fine. They just won't work with Python 3. It's not > like the Python Liberation Front is going to hack into your computer in the > middle of the night and delete you 2.x installation. > --- > -Bill Hamilton Yes, considering this to be more like a fork then an upgrade is the wise approach. Many Linux distributions, for example, will probably ship and concurrently install Python 2.x and Python 3.x for a several years after Python 3 ships. -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: Subprocess with and without shell
George Sakkis <[EMAIL PROTECTED]> wrote: > On May 15, 5:30 am, Nick Craig-Wood <[EMAIL PROTECTED]> wrote: >> George Sakkis <[EMAIL PROTECTED]> wrote: >>> I'm trying to figure out why Popen captures the stderr of a specific >>> command when it runs through the shell but not without it. IOW: >>> cmd = [my_exe, arg1, arg2, ..., argN] >>> if 1: # this captures both stdout and stderr as expected >>> pipe = Popen(' '.join(cmd), shell=True, stderr=PIPE, stdout=PIPE) >>> else: # this captures only stdout >>> pipe = Popen(cmd, shell=False, stderr=PIPE, stdout=PIPE) >>> # this prints the empty string if not run through the shell >>> print "stderr:", pipe.stderr.read() >>> # this prints correctly in both cases >>> print "stdout:", pipe.stdout.read() >>> Any hints ? >> Post an example which replicates the problem! > I would, but the specific executable being spawned is not a python > script, it's a compiled binary (it's not an extension module either; > it's totally unrelated to python). I don't claim there is a bug or > anything suspicious about Popen, but rather I'd like an explanation of > how can a program display different behavior depending on whether it > runs through the shell or not. > George Well, I would try inspecting your environment ... in the shell and from within your Python process. See if there's anything there. If run a command via an interactive shell and it behaves differently when run via Popen then see if perhaps it's doing something like checking to see if it's stdin, or stdout are TTYs (using the C library functions like isatty() for example). You might try running the program under a Pexpect rather than SubProcess (since Pexpect will run the process with it's std* descriptors connected to pty devices). Alternatively try running the program in a shell pipeline to see if it behaves more like you're seeing when you run it under Python. (Since running it in the middle of a pipeline, perhaps with 2>&1 as well, is ensuring that all of the std* descriptors are connected to pipes. (You could also run with 2>/tmp/some.FIFO after doing a mknod p /tmp/some.FIFO (Linux) or mkfifo /tmp/some.FIFO (BSD) to create the named pipe, of course). If none of that worked ... try running the program under stace, truss, ktrace or whatever system call tracing facility your OS provides ... or under gdb. -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: Re printing on same line.
Robert Bauck Hamar <[EMAIL PROTECTED]> wrote: > Jerry Hill wrote: >> On 6/15/07, HMS Surprise <[EMAIL PROTECTED]> wrote: >>> I want to print a count down timer on the same line. I tried >>> print '\r', timeLeft, >>> which just appends to the same line. >> Sounds to me like whatever you're printing to doesn't do what you >> expect when it encounters a carriage return (\r). Is your program >> running in a terminal? Both the windows cmd.exe shell and bash under >> linux seem to do the right thing when encountering a '\r'. > Actually, bash has nothing to do with how the terminal handles \r. The job > of the shell (bash, ksh, csh, sh ...) is to execute your script when you > type its name. > Outputting a \r might or might not move the cursor to the beginning of the > line. It's completely system specific, and even on the same OS, it depends > on the capabilities of the actual terminal the programs run on, and on some > terminal emulators it might depend on configuration settings. > If you need to explore the capabilities of the terminal, curses will be a > good place to start. > -- > rbh Sometimes you don't want to full curses mode switch and other baggage. You can use the 'tput' utility to get the terminal escape sequences for various cursor movements for your terminal. Read the tput man page for some information, and the terminfo(5) man page for more. In particular you can do things like (from a shell prompt): tput sc; tput cup 0 30;echo Front and Center; tput rc ... which saves the current cursor location (sc), executes a cursor position to the first line, 30th column (cup 0 30), writes some text there, and then restores the cursor location (rc). The trick, in Python, is that you can read these sequences into your program via popen() calls and then print them wherever you want to use them. You can even set colors (foreground and background), and text attributes (dim, bright, blinking, underline) and perform various other curses like applications without actually doing the curses mode changes if you're really a bit masochistic. However, for the original poster's purposes the easiest option would probably be to print something like: print chr(0x08) * 80, "new line stuff" + " " * 66 (Print lots of backspaces followed by whatever information you wanted to over-write the line with and padding with enough spaces to clear any other stuff you wanted to over-write). Yes, this is sloppy. Yes, it might not work on some terminals or under some terminal settings. However, it should work under most circumstances on most terminals --- including some which wouldn't support the curses module. You can improve it somewhat by keeping track of how many characters you've printed to the current (last) line and dynamically printing the precise number of backspaces and padding spaces that are needed. -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: how to kill a process
Richard Rossel <[EMAIL PROTECTED]> wrote: > Hi Fellows, > I have a problem with process termination. I have a python code that > apache runs through a django interface. > The code is very simple, first, it creates a process with the > subprocess.Popen call, and afterwards, (using a web request) the > python code uses the PID of the previously created process(stored in a > db) and kills it with an os.kill call using the SIGKILL signal. > The creation of the process is ok, apache calls the python code, this > code creates the process and exits leaving the process up and > running :) > But when the python code is called to kill the created process, the > process is left in a zombie state. A zombie is an entry in the process table that stores the exit value of a deceased process. (The word is a bit of a misnomer ... and the better term would be "death certificate"). You want to do an os.wait() to clear that entry. (The process is well and truly dead after this sort of os.kill() but the system still wants the parent process to be able to retrieve the exit value and this is the Unix/Linux mechanism for storing that). > The kill code that I'm using is: > os.kill(pid, signal.SIGKILL) > and I also tried: > kill_proc = Popen("kill -9 " + pid, shell=true) > but with no success. The misunderstanding here is that you *were* successful. You have killed the process. It's dead. Nothing's left but a death certificate (or "gravestone" or "corpse" or whatever you want to call it). All that remains is for the parent to drop by the morgue (the process table) and pick up the remains. > I suppose that the reason maybe that the python code exits before the > kill call has finished, > so I tried with a while loop until kill_proc.poll() != None, but > without success too :( > do you know what is what I'm doing wrong? You are fundamentally misunderstanding the nature of the process table and the meaning of "zombie." Don't feel bad. It's a very common misunderstanding which has sadly been very poorly addressed by books on Unix systems administration and programming. > thanks very much.- Glad to help. Try this: os.kill(pid, signal.SIGKILL) killedpid, stat = os.waitpid(pid, os.WNOHANG) if killedpid == 0: print >> sys.stderr, "ACK! PROCESS NOT KILLED?" ... I'm using the "WNOHANG" flag here so that the os.waitpid() function will return a tuple of (0,0) if the process isn't dead yet. (Shouldn't be possible under these circumstances, but understanding how to do this in non-blocking mode is better than using the same code pattern in some other case and then being surprised, probably unpleasantly, when your process is blocked by the call). -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: Convert String to Int and Arithmetic
tereglow <[EMAIL PROTECTED]> wrote: > Hello, > I am a complete newbie to Python and am accustomed to coding in PHP/ > Perl/Shell. I am trying to do the following: > I have a string: > cpuSpeed = 'Speed: 10' > What I would like to do is extract the '10' from the string, > and divide that by 1000 twice to get the speed of a processor in MHz. > My understanding is that I need to 'import re' and then use re.split > to get the first part done. The second part confuses me because I'm > unable to convert the '10' to an integer to run division > against it. > Basically, I want to come out with 1000 for the above string. Any > help would be appreciated. > Tom The most obvious approach, rather hard-coded to the example, would be: cpuMhz = float(cpuSpeed[6:]) / 10 ** 6 ... take a "slice" of the string, cpuSpeed, from character seven (zero-based) to the end of the string (cpuSpeed[6:]) and try to convert it into a floating point number (with the float() function) and then divide that by the one million -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: logging module and threading
Ross Boylan <[EMAIL PROTECTED]> wrote: > I would like my different threads to log without stepping on each > other. > Past advice on this list (that I've found) mostly says to send the > messages to a Queue. That would work, but bypasses the logging > module's facilities. > The logging module itself is "thread-safe", but I think that just > means that individual output is protected. If I have, in temporarly > sequence: > thread 1: warning("A") > thread 2: info("something") > thread 1: warning("B") > then I think I'll get them output in this order. It's thread-safe in > that the log will not end up with an entry like > A > some > B > thing > (I think). But I want to get, for example, > A > B > something > What I would like is for each thread to emit a chunk of log messages > when it finishes a unit of work. This sounds like a job for the Queue class/module to me. Could you create a Queue such that all your worker threads are producers to it and you have one dedicated thread as a consumer that relays log entries from the Queue into your loggers? -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: Dynamic subclassing ?
Karlo Lozovina <[EMAIL PROTECTED]> wrote: > manatlan wrote: >> I can't find the trick, but i'm pretty sure it's possible in an easy >> way. > It's somewhat easy, boot looks ugly to me. Maybe someone has a more > elegant solution: > In [6]: import new > In [13]: class Button: >: def buttonFunc(self): >: pass > In [14]: class ExtensionClass: >: def extendedMethod(self): >: pass > In [15]: hybrid = new.instance(Button, > Button.__dict__.update(ExtensionClass.__dict__)) > In [17]: dir(hybrid) > Out[17]: ['__doc__', '__module__', 'buttonFunc', 'extendedMethod'] > Seems to do what you want it to do. > HTH, > Karlo. When I try something like this I run into a little problem: class Foo: def foo(self): return "foo" class Bar: def bar(self): return "bar" f = Foo() f.__dict__.update(Bar.__dict__) ... the problem is that while f now has a "bar" method it doesn't work quite like a normal instance method: >>> f.bar() Traceback (most recent call last): File "", line 1, in ? TypeError: bar() takes exactly 1 argument (0 given) >>> ... though I can get by with f.bar(f) This "new" module seems to be the key to it all; but the only docs I have for that say: >>> help(new) Help on module new: NAME new - Create new objects of various types. Deprecated. FILE /usr/lib/python2.4/new.py MODULE DOCS http://www.python.org/doc/current/lib/module-new.html DESCRIPTION This module is no longer required except for backward compatibility. Objects of most types can now be created by calling the type object. ... which sounds like a bad idea (from the word "Deprecated"). -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: need help with python
[EMAIL PROTECTED] wrote: > On May 11, 10:16 pm, Paul McGuire <[EMAIL PROTECTED]> wrote: >> On May 11, 9:41 pm, [EMAIL PROTECTED] wrote: [... much ellided ...] ["ellided" is a fancy word for "left out" or "replaced with ellipses."] > I was looking around in my Python folder and saw something to do with > that IDLE thing you were talking about. When I right clicked on a .py > file, it said edit with IDLE. I opened it and it was my code but each > line was a different color. It looked confusing so I decide to save > it for later. I knew that I could get the run thing to do the command > thing, but I had forgotten how to get the black window to come up. Idle is an "IDE" (integrated development environment). It's sort of like an editor and a "terminal window" ("command shell") combined. The different colors are the result of a feature called "syntax highlighting" which is available in most of the modern IDEs and better text editors. To "get the black window to come up" use the [Start] menu, choose the "Run" option and type in the name of the program: "cmd" (then hit [Enter]). You can can also find it if you chase far enough down the various sub-menus off the [Start] menu. > Ok. Well, I tried to us the cmd window. It says python: can't open > file 'area.py' I'm guessing that's not good. It won't open any of > my .py files. It's because of where I saved them. I can see how this > i going to work now. Ok so I'll just move them to the place that the > command line says. Now it still won't run my other program: Yes it's because of where you saved them and because of where the command prompt (The C:\> thing that you see inside the "terminal window"). Rather than moving your .py files to wherever your prompt is pointing, it's generally better to change your prompt to point to the right place. For example if you've been saving you .py files to "C:\My Documents" then type: cd "\My Documents" ... (with the quotes around it). Then try to run your files from there. > # Area calculation program > print "Welcome to the Area calculation program" > print "-" > print > # Print out the menu: > print "Please select a shape:" > print "1 Rectangle" > print "2 Circle" > # Get the user's choice: > shape = input("> ") > # Calculate the area: > if shape == 1: >height = input("Please enter the height: ") >width = input("Please enter the width: ") >area = height*width >print "The area is", area > else: >radius = input("Please enter the radius: ") >area = 3.14*(radius**2) >print "The area is", area > Perhaps it isn't written correctly. I don't think it likes the pound > signs. I'm not sure. But, I did go to that mailing list you > recommended. Thanks for that. The pound signs are used by Python to mark "comments" (stuff the Python interpreter ignores; that's there just as hints and reminders to humans who are reading the source code). So, from the first # sign on a line until the end of the line Python is ignoring everything. The only exceptions to this rule are when the # is inside quotes: print "This is technically called an octothorpe: #. See?" ... in that line the octothorpe (#) is part of a quoted string so it and the text following it are NOT ignored. Incidentally, I would use the raw_input() function in place of the input() function that these examples have been using. The problem with the Python input() function is that it parses the input as if it were Python code. So it will raise an exception for any input you enter which is NOT valid, legal Python code. (So far you've been lucky in that you've only been using it to enter simple numbers, which are, of course, valid Python expressions. You can actually get away with inserting one line: input = raw_input ... near the beginning of any of your code examples to alleviate this issue. The raw_input() function will accept any string you can enter up to the first [Enter] key. (Actually on my platform, Linux, it's possible to embed newline and/or carriage return characters --- the ASCII characters which are normally generated by the [Enter] key on various computing platforms --- into a raw_input() value by preceding each of them with a Ctrl-V key. Just off hand I don't know if that works under Windows using a command prompt window. Just pointing that out for other readers to make the observation that Python's raw_input() might not be as "raw" as you might expect). -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: PyGTK : a NEW simple way to code an app
manatlan <[EMAIL PROTECTED]> wrote: > I was a fan of "SimpleGladeApp/tepache way" to build a pygtk app. > I've build a new efficient/dynamic way to build a pygtk app ... > Here is an example : > = > class Fen(GladeApp): >""" >Window win >.title="Hello" >@delete_event >VBox >HBox >Label jo >.label="kokotte" >entry myEntry >.text="kuku" >gtkBuTTon b2 >.label="33" >@clicked >Label jo >.label="koko" >Button b >.label="3" >@clicked >""" >def init(self,m): >self.jo.set_text(m) >pass >def on_b_clicked(self,*a): >self.quit(3) >def on_b2_clicked(self,*a): >self.quit(33) >def on_win_delete_event(self,*args): >self.quit(4) > f=Fen("koko2") > print f.loop() > = > How it works : > in fact, the __doc__ is converted as a "glade file" > the tree of object is indented (like python way) > you can see some common pygtk widget ... > line starting with a dot is an property of the parent object. > line starting with a @ is a declaration of a event of the parent > object. > widgets are not case sensitive, and can start with "Gtk". If a second > word is provided it will be used as an "id", otherwise an unique id > will be build according the type of widget. > the window is created with glade, widgets are provided as attributs of > the instance, and signals are autoconnected on method > "on_[widgetId]_[event](self,*args)" (if a signal is missing in your > class, it warns you at run time) > It will not replace the use of glade-3 for complex widget ... but I > think it's an easy way to code very easily/quickly a simple pygtk > window/form. > I think it could be really useful/handly for beginners too. > for people which are involved in pygtk/python/gui ... i'd like to hear > your comments/ideas ... > Rq: > i don't provide the code now, but it will be released in next version > of "GladeApp" ( http://manatlan.infogami.com/GladeApp ) > it works already, but i need to make "packing properties available" > too ... I'd be a little leery of overloading the __doc__ strings in this way. (They are overloaded enough when used for doctest strings ... but those can serve a legitimate documentary purpose and other doctests can be stored separately). Perhaps it would make sense to standardize on a defined member name such as: GTK__Glade. The rest of your code could remain the same. Are there any other Python projects using other "magically introspected strings" approaches? I thought I saw something being used by some "programming by contract" or some AOP (aspect oriented programming) tools that might be using something like this. -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: 4 byte integer
Paul D Ainsworth <[EMAIL PROTECTED]> wrote: > Greetings everyone. I'm a relative newcomer to python and I have a technical > problem. > I want to split a 32 bit / 4 byte unsigned integer into 4 separate byte > variables according to the following logic: - > bit numbers 0..7 byte 1 > bit numbers 8..15 byte 2 > bit numbers 16..23 byte 3 > bit numbers 24..31 byte 4 > Each of these byte variables to contain integer data from 0 to 255 (or 0 to > FF in hex mode) > I had thought that struct.unpack with an input message format of 'I' would > be the way to do it, but its reporting an error that it doesn't want to > accept an integer. > Please can anyone advise? Would something like this work? def word2bytes(n): """Given an positive integer n, return a tuple of 4 bytes from n's least significant 32-bits """ r = [] n &= 0xL for i in range(4): r.append(n & 0xFF) n >>= 8 r.reverse() return tuple(r) -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: How Can I Increase the Speed of a Large Number of Date Conversions
Some Other Guy <[EMAIL PROTECTED]> wrote: > vdicarlo wrote: >> I am a programming amateur and a Python newbie who needs to convert >> about 100,000,000 strings of the form "1999-12-30" into ordinal dates >> for sorting, comparison, and calculations. Though my script does a ton >> of heavy calculational lifting (for which numpy and psyco are a >> blessing) besides converting dates, it still seems to like to linger >> in the datetime and time libraries. (Maybe there's a hot module in >> there with a cute little function and an impressive set of >> attributes.) > ... >> dateTuple = time.strptime("2005-12-19", '%Y-%m-%d') >> dateTuple = dateTuple[:3] >> date = datetime.date(dateTuple[0], dateTuple[1], >> dateTuple[2]) >> ratingDateOrd = date.toordinal() > There's nothing terribly wrong with that, although strptime() is overkill > if you already know the date format. You could get the date like this: > date = apply(datetime.date, map(int, "2005-12-19".split('-'))) > But, more importantly... 100,000,000 individual dates would cover 274000 > years! Do you really need that much?? You could just precompute a > dictionary that maps a date string to the ordinal for the last 50 years > or so. That's only 18250 entries, and can be computed in less than a second. > Lookups after that will be near instantaneous: For that matter why not memoize the results of each conversion (toss it in a dictionary and precede each conversion with a check like: if this_date in datecache: return datecache[this_date] else: ret=convert(this_date); datecache[this_date]=ret; return ret) (If you don't believe that will help, consider that a memo-ized implementation of a recursive Fibonacci function runs about as quickly as iterative approach). -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie question about string(passing by ref)
Duncan Booth <[EMAIL PROTECTED]> wrote: > lazy <[EMAIL PROTECTED]> wrote: >> I want to pass a string by reference. I understand that strings are >> immutable, but Im not >> going to change the string in the function, just to aviod the overhead >> of copying(when pass-by-value) because the >> strings are long and this function will be called over and over >> again. > You'll find it is pretty hard to get Python to copy a string even if you > wanted it to. About the only way is to break it apart and then construct a > new string with the same value from it. This, of course, is an implementation detail. There are other programming languages which use "interned" objects and, as far as I know, they are considered implementation details with undefined semantics. (In other words you are supposed to ignore this detail and not rely on the identity of any particular objects except those which are defined as such by the language). (An example, in Python, of an object with a defined identity would be "None" --- all references to "None" are intentionally references to a single object and it is the most notable case where the "is" operator is preferred). That said it seems to be trivially easy to "copy" a short string in the version of Python I'm using here: Python 2.4.4 (#2, Oct 20 2006, 00:23:25) [GCC 4.1.2 20061015 (prerelease) (Debian 4.1.1-16.1)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> foo = "foo" >>> bar = "".join(list(foo)) >>> id(foo); id(bar); foo is bar -1211235616 -1211235296 False >>> -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie question about string(passing by ref)
Steven D'Aprano <[EMAIL PROTECTED]> wrote: ... > Python does NOT support pass by reference. Nor does it do pass by value. > Both of those models might describe what other languages do, but they > don't describe what Python does. > Python's passing model is different from both pass by reference and pass > by value, and there are circumstances where Python seems to be acting as > if it were doing one or the other. But it isn't. The model Python uses is > often (but not often enough...) called "pass by object" or "call by > sharing". > http://effbot.org/zone/call-by-object.htm > Steven. Wouldn't it make sense to say that Python passes arguments by binding objects to parameter names? Thus, once you understand the concepts of "names" (vs. "variables") and "binding" (by contrast to "assignment") then you also understand the argument passing model in the same terms. Also, wouldn't it be fair to say that the class and def statements also bind names to objects (callable and class objects respectively). -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: append
Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > HMS Surprise a ?crit : >> Trying not to be a whiner but I sure have trouble finding syntax in >> the reference material. I want to know about list operations such as >> append. > The only thing you have to know is that it doesn't exists. Python > strings are immutables. If you want to sequentially build a string, you > can either rebind the name to a new string : Huh? Where did strings come into this question? > s = "" > for c in "abcdef": > s += c Huh? Why not just use: s = list(s)? For a more clear example: >>> list("foo") ['f', 'o', 'o'] See? > or collect substrings in a list and join it: > s = [] > for c in "abcdef": > s.append(c) > s = "".join(s) Yes, "".join(list("foo")) is a sort of "expensive" no-op. As for the original post: dir() and help() from the interactive prompt are good friends. An ipython prompt is an even better friend to have while learning python. Consider this: In[1]:list.app[[Tab]] ... list.append In[1]:list.append[[?]][[Enter]] Type: method_descriptor Base Class: String Form: Namespace: Python builtin Docstring: L.append(object) -- append object to end In[2]: ... where I'm highlighting some keystrokes with [[]] marks. The point is that ipython offers [Tab] completion(*) and has a number other cool features. For example if you end a function/method/class/member line with a ? key and hit enter, then you get a help screen as shown in my mini-transcript above. Python simply has the best interactive introspection features around. (Also, if you use docstrings in your own code than these features will work on your code, too). For extra fun go into one of your directories which contains some of your .py files, and/or add a few such directories to your PYTHONPATH environment variable. Then start up a command like: pydoc -p 8080 ... or pick some other TCP port. Then point a web browser at localhost:8080 ... ... see? There's a mini-web service with clickable links to read the docs for all the Python modules installed on your system ... including your own code! * ([Tab]-completion is also possible in the normal python >>> interpreter using: import rlcompleter ... and then calling the relatively obscure incantation: rlcompleter.readline.parse_and_bind("tab: complete") If, like me you prefer vi-mode readline editing then you add another incantation: rlcompleter.readline.parse_and_bind("set editing-mode vi") ... or you can simply put the following in you ~/.inputrc: $if python set editing-mode vi $endif ... and, in that case, you can bind other keystrokes into macro strings like: C-o:"import sys,os" or whatever). -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: python shell
[EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > On May 16, 12:38 pm, Krypto <[EMAIL PROTECTED]> wrote: >> I have been using python shell to test small parts of the big program. >> What other ways can I use the shell effectively. My mentor told me >> that you can virtually do anything from testing your program to >> anything in the shell. Any incite would be useful. > Yeah? Well tell your mentor he can take his programs and > his literal interpretaions to the other side of the river!! > Oh...wait. Did you mean "insight"? > One thing that covers a LOT of ground is you can run other > programs from the shell and capture their output (assuming > the output is text to stdout). > For example, I can run the program factor!.exe from the > command line: > C:\python25\user>factor!.exe 27 > PRIME_FACTOR 3 > PRIME_FACTOR 3 > PRIME_FACTOR 3 > But I can also run it from the Python shell: import os f = os.popen("factor! 27").readlines() f > ['PRIME_FACTOR 3\n', 'PRIME_FACTOR 3\n', 'PRIME_FACTOR > 3\n'] q = [int(i.split()[1]) for i in f] q > [3, 3, 3] > Now, you've got the factors without having to write your own > factoring program and you never had to leave the shell. > What more could you ask for? I could ask for some tricks that would let me do things like: * os.fork() --- but have that spawned in it's own xterm/shell so I can no interact with each of the children separately * Use the curses library --- with the interpreter reading from one shell/xterm and the curses display controlling another one. I'm sure they're out there ... and I've love to see pointers to them. -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: How to do basic CRUD apps with Python
Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > walterbyrd a ?crit : >> With PHP, libraries, apps, etc. to do basic CRUD are everywhere. Ajax >> and non-Ajax solutions abound. >> With Python, finding such library, or apps. seems to be much more >> difficult to find. >> I thought django might be a good way, but I can not seem to get an >> answer on that board. >> I would like to put together a CRUD grid with editable/deletable/ >> addable fields, click on the headers to sort. Something that would >> sort-of looks like an online spreadsheet. It would be nice if the >> fields could be edited in-line, but it's not entirely necessary. >> Are there any Python libraries to do that sort of thing? Can it be >> done with django or cherrypy? > You may want to have a look at turbogears's widgets. Admittedly I had to look up the meaning of CRUD in this context: (http://en.wikipedia.org/wiki/Create%2C_read%2C_update_and_delete create, read, update, and delete). I'm looking at Turbogears' Widgets in another window as I type this ... but it will be awhile before I can comment on how they might apply to the OP's needs. Actually I'm wholly unqualified to comment on his or her needs ... but I can comment on how I interpreted the question. Even with the SQLAlchemy SQLSoup examples there's still an annoying about of boilerplate coding that has to be done in order to create a web application for doing CRUD on a database. The missing element seems to be the ability to autogenerate web forms and reports with the requisite controls in them. Imagine, for a moment, being able to do something like: >>> import sqlalchemy.ext.webcrud as crud >>> db = crud.open() >>> db.displayTopForm() '' ... and having a default "top level" web page generated with options to query the database (or some specific table in the database to be more specific, add new entries, etc). I'm thinking of some sort of class/module that would generate various sorts of HTML forms by default, but also allow one to sub-class each of the form/query types to customize the contents. It would use introspection on the database columns and constraints to automatically generate input fields for each of the columns and even fields for required foreign keys (or links to the CRUD for those tables?). Ideally it would also automatically hide autogenerated (index/key) fields, and map the table column IDs to form names (with gettext support for l10n of those). I think that's the sort of thing the OP was looking for. Not the ORM ... the the glue between the web framework and the ORM. -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: Hello gettext
James T. Dennis <[EMAIL PROTECTED]> wrote: ... just to follow-up my own posting --- as gauche as that is: > You'd think that using things like gettext would be easy. Superficially > it seems well documented in the Library Reference(*). However, it can > be surprisingly difficult to get the external details right. >* http://docs.python.org/lib/node738.html > Here's what I finally came up with as the simplest instructions, suitable > for an "overview of Python programming" class: > Start with the venerable "Hello, World!" program ... slightly modified > to make it ever-so-slightly more "functional:" >#!/usr/bin/env python >import sys >def hello(s="World"): >print "Hello,", s >if __name__ == "__main__": >args = sys.argv[1:] >if len(args): >for each in args: >hello(each) >else: >hello() > ... and add gettext support (and a little os.path handling on the > assumption that our message object files will not be readily > installable into the system /usr/share/locale tree): >#!/usr/bin/env python >import sys, os, gettext >_ = gettext.lgettext >mydir = os.path.realpath(os.path.dirname(sys.argv[0])) >localedir = os.path.join(mydir, "locale") >gettext.bindtextdomain('HelloPython', localedir) >gettext.textdomain('HelloPython') >def hello(s=_("World")): >print _("Hello,"), s Turns out this particular version is a Bad Idea(TM) if you ever try to import this into another script and use it after changing you os.environ['LANG'] value. I mentioned in another message awhile back that I have an aversion to using defaulted arguments other than by setting them as "None" and I hesitated this time and then thought: "Oh, it's fine in this case!" Here's my updated version of this script: --- #!/usr/bin/env python import gettext, os, sys _ = gettext.lgettext i18ndomain = 'HelloPython' mydir = os.path.realpath(os.path.dirname(sys.argv[0])) localedir = os.path.join(mydir, "locale") gettext.install(i18ndomain, localedir=None, unicode=1) gettext.bindtextdomain(i18ndomain, localedir) gettext.textdomain(i18ndomain) def hello(s=None): """Print "Hello, World" (or its equivalent in any supported language): Examples: >>> os.environ['LANG']='' >>> hello() Hello, World >>> os.environ['LANG']='es_ES' >>> hello() Hola, Mundo >>> os.environ['LANG']='fr_FR' >>> hello() Bonjour, Monde """ if s is None: s = _("World") print _("Hello,"), s def test(): import doctest doctest.testmod() if __name__ == "__main__": args = sys.argv[1:] if 'PYDOCTEST' in os.environ and os.environ['PYDOCTEST']: test() elif len(args): for each in args: hello(each) else: hello() --- ... now with doctest support. :) >if __name__ == "__main__": >args = sys.argv[1:] >if len(args): >for each in args: >hello(each) >else: >hello() > Note that I've only added five lines, the two modules to my import > line, and wrapped two strings with the conventional _() function. > This part is easy, and well-documented. > Running pygettext or GNU xgettext (-L or --language=Python) is > also easy and gives us a file like: ># SOME DESCRIPTIVE TITLE. ># Copyright (C) YEAR ORGANIZATION ># FIRST AUTHOR <[EMAIL PROTECTED]>, YEAR. ># >msgid "" >msgstr "" >"Project-Id-Version: PACKAGE VERSION\n" >"POT-Creation-Date: 2007-05-14 12:19+PDT\n" >"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" >"Last-Translator: FULL NAME <[EMAIL PROTECTED]>\n" >"Language-Team: LANGUAGE <[EMAIL PROTECTED]>\n" >"MIME-Version: 1.0\n" >"Content-Type: text/plain; charset=CHARSET\n" >"Content-Transfer-Encoding: ENCODING\n" >"Generated-By: pygettext.py 1.5\n"
Hello gettext
You'd think that using things like gettext would be easy. Superficially it seems well documented in the Library Reference(*). However, it can be surprisingly difficult to get the external details right. * http://docs.python.org/lib/node738.html Here's what I finally came up with as the simplest instructions, suitable for an "overview of Python programming" class: Start with the venerable "Hello, World!" program ... slightly modified to make it ever-so-slightly more "functional:" #!/usr/bin/env python import sys def hello(s="World"): print "Hello,", s if __name__ == "__main__": args = sys.argv[1:] if len(args): for each in args: hello(each) else: hello() ... and add gettext support (and a little os.path handling on the assumption that our message object files will not be readily installable into the system /usr/share/locale tree): #!/usr/bin/env python import sys, os, gettext _ = gettext.lgettext mydir = os.path.realpath(os.path.dirname(sys.argv[0])) localedir = os.path.join(mydir, "locale") gettext.bindtextdomain('HelloPython', localedir) gettext.textdomain('HelloPython') def hello(s=_("World")): print _("Hello,"), s if __name__ == "__main__": args = sys.argv[1:] if len(args): for each in args: hello(each) else: hello() Note that I've only added five lines, the two modules to my import line, and wrapped two strings with the conventional _() function. This part is easy, and well-documented. Running pygettext or GNU xgettext (-L or --language=Python) is also easy and gives us a file like: # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR <[EMAIL PROTECTED]>, YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2007-05-14 12:19+PDT\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <[EMAIL PROTECTED]>\n" "Language-Team: LANGUAGE <[EMAIL PROTECTED]>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: ENCODING\n" "Generated-By: pygettext.py 1.5\n" #: HelloWorld.py:10 msgid "World" msgstr "" #: HelloWorld.py:11 msgid "Hello," msgstr "" ... I suppose I should add the appropriate magic package name, version, author and other values to my source. Anyone remember where those are documented? Does pygettext extract them from the sources and insert them into the .pot? Anyway, I minimally have to change one line thus: "Content-Type: text/plain; charset=utf-8\n" ... and I suppose there are other ways to do this more properly. (Documented where?) I did find that I could either change that in the .pot file or in the individual .po files. However, if I failed to change it then my translations would NOT work and would throw an exception. (Where is the setting to force the _() function to fail gracefully --- falling back to no-translation and NEVER raise exceptions? I seem to recall there is one somewhere --- but I just spent all evening reading the docs and various Google hits to get this far; so please excuse me if it's a blur right now). Now we just copy these templates to individual .po files and make our LC_MESSAGES directories: mkdir locale && mv HelloPython.pot locale cd locale for i in es_ES fr_FR # ... do cp HelloPython.pot HelloPython_$i.po mkdir -p $i/LC_MESSAGES done ... and finally we can work on the translations. We edit each of the _*.po files inserting "Hola" and "Bonjour" and "Mundo" and "Monde" in the appropriate places. And then process these into .mo files and move them into place as follows: for i in *_*.po; do i=${i#*_} msgfmt -o ./${i%.po}/LC_MESSAGES/HelloPython.mo done ... in other words HelloPython_es_ES.po is written to ./es_ES/LC_MESSAGES/HelloPython.mo, etc. This last part was the hardest to get right. To test this we simply run: $HELLO_PATH/HelloPython.py Hello, World export LANG=es_ES $HELLO_PATH/HelloPython.py Hola, Mundo export LANG=fr_FR $HELLO_PATH/HelloPython.py Bonjour, Monde export LANG=zh_ZH $HELLO_PATH/HelloPython.py Hello, World ... and we find that our Spanish and French translations work. (With apologies if my translations are technically wrong). Of course I realize this only barely scratches the surface of I18n and L10n issues. Also I don't know, offhand, how
Re: file uploader
Gabriel Genellina <[EMAIL PROTECTED]> wrote: > En Sun, 13 May 2007 18:41:16 -0300, Sick Monkey <[EMAIL PROTECTED]> > escribi?: >> If anyone has a simpler way of checking to see if >> a file already exists (prior to uploading to a server) and renaming it, >> please let me know. > I will ignore the "server" part... >> Here is the code that I am using (it runs exactly the same as the linux >> app >> 'arcgen'). >> [...] >> t = i-1 >> filename=string.replace(filename,".-%s" % (t),".-%s" % (i)) > If the original filename contained .-1 somewhere, you're modifying it. > This is safer and shorter: > import os,string > filename = "whoa.mp3" > dir_path = "/u01/" > ofilename = filename > i = 0 > while os.path.exists(dir_path+filename): > filename = "%s.-%s" % (ofilename,i) > i += 1 > req.write(filename) Is it really safer? Couldn't their still be a race condition (if some hostile process has write access to the directory in which this is being attempted)? Wouldn't it be safer to import tempfile, use the t=NamedTemporaryFile() function therein and then use try: os.link(t.name, ...) except OSError: to safely rename it? Something like: import os, tempfile tdir = "/u01/" tf = tempfile.NamedTemporaryFile(dir="/u01/" i = 0 while 1: try: os.link(tf.name, os.path.join(tdir, filename) except OSError: i += 1 filename = "%s.-%s" % (filename, i) else: break ...??? -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: track cpu usage of linux application
Fabian Braennstroem <[EMAIL PROTECTED]> wrote: > Hi, >I would like to track the cpu usage of a couple of >programs using python. Maybe it works somehow with >piping 'top' to python read the cpu load for a greped >application and clocking the the first and last >appearence. Is that a good approach or does anyone have >a more elegant way to do that? > Greetings! > Fabian If you're on a Linux system you might be far better accessing the /proc/$PID/stat files directly. The values you'd find therein are documented: http://www.die.net/doc/linux/man/man5/proc.5.html (among other places). Of course you could write you code to look for file and fall back to use the 'ps' command if it fails. In addition you can supply arguments to the 'ps' command to limit it to reporting just on the process(es) in which you are interested ... and to eliminate the header line and irrelevant columns of output. -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: Change serial timeout per read
[EMAIL PROTECTED] wrote: > I'm writing a driver in Python for an old fashioned piece of serial > equipment. Currently I'm using the USPP serial module. From what I can > see all the serial modules seem to set the timeout when you open a > serial port. This is not what I want to do. I need to change the > timeout each time I do a "read" on the serial port, depending on > which part of the protocol I've got to. Sometimes a return character > is expected within half a second, sometimes within 2 seconds, and > sometimes within 20 seconds. How do I do this in USPP, or Pyserial, or > anything else? Currently I'm working in Windows, but I'd prefer a > platform independent solution if possible... > Thanks - Rowan I'm not familiar with the USPP serial module. However, I used the PySerial package successfully for several months on one job to write a full regression testing framework and suite for testing a series of different VOIP/SIP phone models (little embedded Linux systems) via their diagnostics/JTAG serial headers. It had timeout and writeTimeout settings which I recall were fully configurable to fractions of a second, None, and 0 (non-blocking). Under Debian it's available as a simple: apt-get -f install python-serial. ... and I seem to recall that it worked fine under MS Windows, too. (In fact it was written in pure Python, no C-lib or .so/.DLL under it). Ahh ... here's the URL: http://pyserial.sourceforge.net/ ... with backends for CPython (Windows and Linux/UNIX/Posix), and Jython. Under Python just use: >>> import serial ... then use something like: >>> s0 = serial.Serial(0) # Open first serial port: default settings ... or: >>> s0 = serial.Serial('/dev/ttyS0', 38400, timeout=None) \ # port by device node/name, setting speed and no timeout >>> s1 = serial.Serial(3, 19200, timeout=0) \ # another by number, non-blocking Then use: >>> s0.read() # or s0.readline() for '\n' terminated ... and various other methods on these ports. BTW: you can change the timeouts on these connection objects simply by using s0.timeout=X ... and you can set them to floating point values --- so you can use tenths of a second. I remember I was also able to adapt my framework classes to add support for telnetlib in about an hour of spare time one evening; so we could use the serial port to manage testing on one block of phones and we could enable the optional telnet port access built-into a bank of the other phones and use almost all the same test code with them. (The only difference was that we couldn't capture reboot output over the telnet interface; while I could capture and log it via the serial ports --- in other words it was a natural limitation of the hardware --- and their embedded system didn't enable something like a dmesg to capture that after the fact). The reason I mention the telnetlib angle serves some purpose other than mere rambling and bragging ... I seem to recall that the methods supported by the two modules were very closely matched ... so my adaptation was extremely straightforward. I see that USPP (univ. serial port for Python) is available at: http://ibarona.googlepages.com/uspp ... and it's supposed to have most of the same features (from a quick glance at the web page). However, there's much more info available at the PySerial page ... and PySerial seems to be far more recently maintained (with 2.2 "slots' support, for example). In addition PySerial seems to be linked to a PyParallel package that's "under development" (presumably by the same author). (I'm guessing that this latter development can't be done in pure Python, though). -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: Simple Python REGEX Question
johnny <[EMAIL PROTECTED]> wrote: > I need to get the content inside the bracket. > eg. some characters before bracket (3.12345). > I need to get whatever inside the (), in this case 3.12345. > How do you do this with python regular expression? I'm going to presume that you mean something like: I want to extract floating point numerics from parentheses embedded in other, arbitrary, text. Something like: >>> given='adfasdfafd(3.14159265)asdfasdfadsfasf' >>> import re >>> mymatch = re.search(r'\(([0-9.]+)\)', given).groups()[0] >>> mymatch '3.14159265' >>> Of course, as with any time you're contemplating the use of regular expressions, there are lots of questions to consider about the exact requirements here. What if there are more than such pattern? Do you only want the first match per line (or other string)? (That's all my example will give you). What if there are no matches? My example will raise an AttributeError (since the re.search will return the "None" object rather than a match object; and naturally the None object has no ".groups()' method. The following might work better: >>> mymatches = re.findall(r'\(([0-9.]+)\)', given).groups()[0] >>> if len(mymatches): >>> ... ... and, of couse, you might be better with a compiled regexp if you're going to repeast the search on many strings: num_extractor = re.compile(r'\(([0-9.]+)\)') for line in myfile: for num in num_extractor(line): pass # do whatever with all these numbers -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
mmap thoughts
I've been thinking about the Python mmap module quite a bit during the last couple of days. Sadly most of it has just been thinking ... and reading pages from Google searches ... and very little of it as been coding. Mostly it's just academic curiosity (I might be teaching an "overview of programming" class in a few months, and I'd use Python for most of the practical examples to cover a broad range of programming topics, including the whole concept of memory mapping used, on the one hand, as a file access abstraction and as a form of inter-process shared memory, on the other). Initial observations: * The standard library reference could use some good examples. At least of those should show use of both anonymous and named mmap objects as shared memory. * On Linux (various versions) using Python 2.4.x (for at least 2.4.4 and 2.4.2) if I create on mmap'ing in one process, then open the file using 'w' or 'w+' or 'w+b' in another process then my first process dies with "Bus Error" This should probably be documented. (It's fine if I use 'a' (append) modes for opening the file). * It seems that it's also necessary to extend a file to a given size before creating a mapping on it. In other words you can't mmap a newly created, 0-length file. So it seems like the simplest example of a newly created, non-anonymous file mapping would be something like: sz = (1024 * 1024 * 1024 * 2 ) - 1 f=open('/tmp/mmtst.tmp','w+b') f.seek(sz) f.write('\0') f.flush() mm = mmap.mmap(f.fileno(), sz, mmap.MAP_SHARED) f.close() Even creating a zero length file and trying to create a zero-length mapping on it (with mmap(f.fileno(),0,...) ... with a mind towards using mmap's .resize() method on it doesn't work. (raises: EnvironmentError: "Errno 22: Invalid Argument"). BTW: the call to f.flush() does seem to be required at least in my environments (Linux under 2.6 kernels various distributions and the aforementioned 2.4.2 and 2.4.4 versions of Python. * The mmtst.tmp file is "sparse" of course. So its size in the example above is 2GB ... but the disk usage (du command) on it is only a few KB (depending on your filesystem cluster size etc). * Using a function like len(mm[:]) forces the kernel's filesystem to return a huge stream of NUL characters. (And might thrash your system caches a little). * On my SuSE/Novell 10.1 system, using Python 2.4.2 (their RPM 2.4.2-18) I found that anonymous mmaps would raise an EnvironmentError. Using the same code on 2.4.4 on my Debian and Fedora Core 6 system worked with no problem: anonmm == mmap.mmap(-1,4096,mmap.MAP_ANONYMOUS|mmap.MAP_SHARED) ... and also testing on their 2.4.2-18.5 update with the same results: Python 2.4.2 (#1, Oct 13 2006, 17:11:24) [GCC 4.1.0 (SUSE Linux)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import mmap >>> mm = mmap.mmap(-1,4096, mmap.MAP_ANONYMOUS|mmap.MAP_SHARED) Traceback (most recent call last): File "", line 1, in ? EnvironmentError: [Errno 22] Invalid argument >>> [EMAIL PROTECTED]:~> uname -a Linux dhcphostname 2.6.16.13-4-default #1 Wed May 3 ... * On the troublesome SuSE/Novell box using: f = open('/dev/zero','w+') anonmm == mmap.mmap(f.fileno(),4096, mmap.MAP_ANONYMOUS|mmap.MAP_SHARED) ... seems to work. However, a .resize() on that raises the same EnvironmentError I was getting before. * As noted in a few discussions in the past Python's mmap() function doesn't take an "offset" parameter ... it always uses an offset of 0 (It seems like a patch is slated for inclusion in some future release?) * On 32-bit Linux systems (or on systems running a 32-bit compilation of Python) 2GB is, of course, the upper limit of an mmap'ing The ability to map portions of larger files is a key motivation to include the previously mentioned "offset" patch. Other thoughts: (Going beyond initial observations, now) * I haven't tested this, but I presume that anonymous|shared mappings on UNIX can only be shared with child/descendant processes ... since there's no sort of "handle" or "key" that can be passed to unrelated processes via any other IPC method; so only fork() based inheritence will work. * Another thing I haven't tested, yet: how robust are shared mappings to adjacent/non-overlapping concurrent writes by multiple processes? I'm hoping that you can reliably have processes writing updates to small, pre-assigned, blocks in the mmap'ing without contention issues. I plan to write some "hammer test" code to test this theory ... and run it for awhile on a few multi-core/SMP systems. * It would be nice to bu
Re: Minor bug in tempfile module (possibly __doc__ error)
Marc Christiansen <[EMAIL PROTECTED]> wrote: > James T. Dennis <[EMAIL PROTECTED]> scribis: >> In fact I realized, after reading through tempfile.py in /usr/lib/... >> that the following also doesn't "work" like I'd expect: >># foo.py >>tst = "foo" >>def getTst(arg): > If I change this line: >>return "foo-%s" % arg > to: > return "%s-%s" % (tst, arg) >># bar.py >>import foo >>foo.tst = "bar" >>print foo.getTst("testing") >>foo-testing <<<- NOT "bar-testing" > Then "python bar.py" prints "bar-testing". >0:[EMAIL PROTECTED]:/tmp> cat foo.py >tst = "foo" >def getTst(arg): >return "%s-%s" % (tst,arg) >0:[EMAIL PROTECTED]:/tmp> cat bar.py >import foo >foo.tst = "bar" >print foo.getTst("testing") >0:[EMAIL PROTECTED]:/tmp> python bar.py >bar-testing > And regarding the tempfile.template problem, this looks like a bug. > Because all functions in tempfile taking a prefix argument use "def > function(... , prefix=template, ...)", only the value of template at > import time matters. > Adia?, Marc I suppose my real sample code was def getTst(arg=tst): Oddly I've never come across that (the fact that defaulted arguments are evaluated during function definition) in my own coding and I guess there are two reasons for that: I try to avoid global variables and I usually use defaulted variables of the form: def (foo=None): if foo is None: foo = self.default_foo -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: Minor bug in tempfile module (possibly __doc__ error)
Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote: > In <[EMAIL PROTECTED]>, James T. Dennis wrote: >> Tonight I discovered something odd in the __doc__ for tempfile >> as shipped with Python 2.4.4 and 2.5: it says: >> >> This module also provides some data items to the user: >> >> TMP_MAX - maximum number of names that will be tried before >>giving up. >> template - the default prefix for all temporary names. >>You may change this to control the default prefix. >> >> ... which would lead one to think that the following code would work: >> >> >>> import tempfile >> >>> tempfile.template = 'mytest' >> >>> tf = tempfile.NamedTemporaryFile() >> >>> tf.name >> '/tmp/mytest-XX' >> >> It doesn't. > The source says: > __all__ = [ >"NamedTemporaryFile", "TemporaryFile", # high level safe interfaces >"mkstemp", "mkdtemp", # low level safe interfaces >"mktemp", # deprecated unsafe interface >"TMP_MAX", "gettempprefix",# constants >"tempdir", "gettempdir" > ] > Maybe the doc should be clearer in saying "constants" too. >> Secondly, the author(s) of the tempfile module apparently didn't >> understand this either. And no one else even noticed that the __doc__ >> is wrong (or at least misleading -- since the only way I can see to >> change tempfile.template is to edit the .py file! > You can change it by simply assigning to the name: > In [15]: tempfile.template = 'spam' > In [16]: tempfile.template > Out[16]: 'spam' I know you can change it. But changing it in your namespace doesn't change the results returned by the functions called from the module. > If you want to change the outcome of the functions and objects then simply > give the prefix as argument. I know how to provide the prefix arguments and that was never the issue. The issue was twofold: The docs are wrong (or at least confusing/misleading) I don't quite understand how this name/variable in my namespace (__main__) is able to change the value while the functions in the module still hold the old value. -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Re: Minor bug in tempfile module (possibly __doc__ error)
Dennis Lee Bieber <[EMAIL PROTECTED]> wrote: > On Wed, 09 May 2007 06:50:38 -0000, "James T. Dennis" > <[EMAIL PROTECTED]> declaimed the following in comp.lang.python: >> In fact I realized, after reading through tempfile.py in /usr/lib/... >> that the following also doesn't "work" like I'd expect: >> >No idea of the tempfile problem, but... > >> # foo.py >> tst = "foo" >> def getTst(arg): >> return "foo-%s" % arg >This return is using a literal "foo-". Change it to >return "%s-%s" % (tst, arg) Sorry that was a retyping bug in my posting ... not in my sample code which was on another system. > and try again. Try it yourself. As I said ... the value of tst in your name space will be changed, but the value returned by functions in the imported module will still use the old value! -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list
Minor bug in tempfile module (possibly __doc__ error)
Tonight I discovered something odd in the __doc__ for tempfile as shipped with Python 2.4.4 and 2.5: it says: This module also provides some data items to the user: TMP_MAX - maximum number of names that will be tried before giving up. template - the default prefix for all temporary names. You may change this to control the default prefix. ... which would lead one to think that the following code would work: >>> import tempfile >>> tempfile.template = 'mytest' >>> tf = tempfile.NamedTemporaryFile() >>> tf.name '/tmp/mytest-XX' It doesn't. In fact I realized, after reading through tempfile.py in /usr/lib/... that the following also doesn't "work" like I'd expect: # foo.py tst = "foo" def getTst(arg): return "foo-%s" % arg # bar.py import foo foo.tst = "bar" print foo.getTst("testing") foo-testing <<<- NOT "bar-testing" Now I would feel like a real idiot if I'd come across that in the foo/bar case here ... because I clearly don't understand quite *why* I can't "monkey patch" this value. I would ... but I don't. First, I wouldn't have written code like this foo/bar stuff; except to test my hypothesis about why changes to tempfile.template don't actually affect the values seen by functions in the tempfile namespace. Secondly, the author(s) of the tempfile module apparently didn't understand this either. And no one else even noticed that the __doc__ is wrong (or at least misleading -- since the only way I can see to change tempfile.template is to edit the .py file! So, I don't feel like an idiot. But I am curious ... ... why can't I change that value in that other namespace? Is it a closure? (Or like a closure?) Where is this particular aspect of the import/namespace semantics documented? -- Jim Dennis, Starshine: Signed, Sealed, Delivered -- http://mail.python.org/mailman/listinfo/python-list