Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Habnabit
Dec 30, 2007

lift your skinny fists like
antennas in germany.
Anti-recommending web.py here. If you want a minimalist framework, use werkzeug. It's more flexible if you ever need the flexibility, instead of caging you in if you ever try to do something beyond what the standard thing provides.

Also, use python 2.6 and not 3.0. As far as I know, there's no (decent) web frameworks ported to 3.x yet. There's discussions of why 2.x over 3.x earlier in this thread as well as in the "python 3.0 released" thread.

And the sooner you learn about the MVC paradigm, the better. Jamming all of your application logic into your templates is so bad. :(

Adbot
ADBOT LOVES YOU

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...
A headscratcher here: I registered and uploaded a new package to PyPi and only subsequently noticed that my documentation (a 'docs' dir in the top level of a setuptools enabled project) hadn't been included in the distribution. I'm sure this used to work, but setuptools doesn't want to include anything that isn't a strict Python package in a distribution. Weird. The setuptools documentation makes an aside that docs will be including in a generated source distribution, but that's not the case. So what gives? Sure I could manually tar the file and upload it but that defeats the point of 'python setup.py sdist upload'.

Jo
Jan 24, 2005

:allears:
Soiled Meat
What is the elegant/correct way to write a function that will iterate across both a list and a dictionary correctly.

I'd like to say...
code:
  for i in thisThing:
    i.doSomething()
rather than...
code:
  if i instanceof dict:
    for i in thisThing:
      thisThing[i].doSomething()
  elif i instanceof list:
    for i in thisThing:
      i.doSomething()

Scaevolus
Apr 16, 2007

Jo posted:

What is the elegant/correct way to write a function that will iterate across both a list and a dictionary correctly.

You know about dict.itervalues(), right?

Jo
Jan 24, 2005

:allears:
Soiled Meat

Scaevolus posted:

You know about dict.itervalues(), right?

I do now. :saddowns:

Still, that means when calling the function I'd have to say
code:
  if thisThing instanceof dict:
    for i in thisThing.itervalues():
      i.doSomething()
  elif thisThing instanceof list:
    for i in thisThing:
      i.doSomething()
which, while an improvement, is still not quite as neutral as I'd like.

EDIT: For more clarity, I'm curious about accessing in a very duck-typed object friendly style the iterators for lists and dictionaries. If this isn't possible, it's not a big deal. Just want to know if I'm missing something obvious.

Jo fucked around with this message at 01:14 on May 7, 2009

ShizCakes
Jul 16, 2001
BANNED

Habnabit, tbradshaw, deimos posted:

Advice about getting into python as a web language.

I really appreciate everyone's input. I wanted to start with 3.0 because I didn't want to teach myself syntactical things like the print statement vs. function bit twice - it would annoy the bejesus out of me. Thankfully, because of your input, I looked harder at 2.6 and saw that most common hangups from 3 are available in 2.6 (which is by design, I know). So I've dropped down to 2.6, which has now opened up a whole world of possibility for me.

The only thing that you guys haven't answered for me, and I am hoping someone can point me in the right direction, is that I'd really like to avoid the "handles all paths" style of web application. I think it's absolutely asinine that I should have to configure apache to lock a webapp down into a subdirectory. What I really long for is the PHP style of being able to drop a PHP file anywhere and have ONLY that php file be callable. If I want parameters, I have to pass them with ?. Is this possible?

EDIT: What I guess I am looking for is possibly a templating framework for Python? I am looking at them right now, but any pointers would be great.

ShizCakes fucked around with this message at 01:22 on May 7, 2009

Jo
Jan 24, 2005

:allears:
Soiled Meat

ShizCakes posted:

The only thing that you guys haven't answered for me, and I am hoping someone can point me in the right direction, is that I'd really like to avoid the "handles all paths" style of web application. I think it's absolutely asinine that I should have to configure apache to lock a webapp down into a subdirectory. What I really long for is the PHP style of being able to drop a PHP file anywhere and have ONLY that php file be callable. If I want parameters, I have to pass them with ?. Is this possible?

EDIT: What I guess I am looking for is possibly a templating framework for Python? I am looking at them right now, but any pointers would be great.

I know that web.py provides the ability to use templates and gather parameters passed either in the form of urls
http://www.omgitswebsite.com/this/is/aSetOfValues through clever use of url handlers
OR
http://www.omgitswebsite.com/this?is=aSetOfValues through web.input( is ).

However, web.py won't do the folder/file specific sort of thing you want. You can't just drop python code into a page like PHP.

Edit: Something of a hack in web.py to do something close.
In the $webroot/templates/default.html:
code:
$def with (content)
<HTML>
<BODY>
$:content <!-- The : after the $ says 'don't escape web syntax. -->
</BODY>
</HTML>
In the $webroot/code.py
code:

import web

urls = ( 
'/', 'index',
'/thisFolder/thisFile', 'thatFolderThatFile'
)

app = web.application( urlHandlers, globals() )
render = web.template.render( 'templates/' )

class index:
  def GET( self ):
    content = "This will show up when someone browses the root."
    return render.default( content ) # Note how default corresponds to the template name

class thatFolderThatFile:
  def GET( self ):
    data = web.input( selection = "" )
    content = "Oh snap, someone accessed mywebpage.com/thisFolder/thisFile.htm and also, someone added " + str( data.selection )
    return render.default( content )

if __name__ == "__main__":
  app.run()

Jo fucked around with this message at 01:40 on May 7, 2009

Scaevolus
Apr 16, 2007

Jo posted:

I do now. :saddowns:
which, while an improvement, is still not quite as neutral as I'd like.
What about this?

code:
  if thisThing instanceof dict:
    iterable = thisThing.itervalues()
  else:
    iterable = iter(thisThing)
  for i in iterable:
    i.doSomething()

Jo
Jan 24, 2005

:allears:
Soiled Meat

Scaevolus posted:

What about this?

code:
  if thisThing instanceof dict:
    iterable = thisThing.itervalues()
  else:
    iterable = iter(thisThing)
  for i in iterable:
    i.doSomething()

Had something like that before the edit. :shobon: I didn't think that one could do `for i in iterator` since an iterator does not itself return items, just moves through the items.
To be more clear:
`for i in thisThing:`
`i` is an iterator.
`in thisThing` returns an iterator

Or I could be out of my mind.

EDIT: Works! o>-<

Jo fucked around with this message at 01:47 on May 7, 2009

hlfrk414
Dec 31, 2008

Jo posted:

`for i in thisThing:`
`i` is an iterator.
`in thisThing` returns an iterator

No

code:
>>> values = [1,2,3]
>>> for val in values:
	print( type(val))
	break

<class 'int'>
>>> iterator = iter(values)
>>> type(iterator)
<class 'list_iterator'>
>>> for i in iterator:
	print( type(i))
	break

<class 'int'>
When you say "for x in sequence", python calls the special method __iter__ which is supposed to give back an iterator. It may do what it wants. (Calling __iter__ on an iterator generally makes it return itself.) Calling it on a sequence like a list should return an iterator object, which has a __next__ method that will either give back a value or generate an exception. The for loop will call __next__ repeatedly, and assigns the value to the variable name ("x" in the case of "for x in sequence".) The loop will catch a StopIteration exception at the end and then it knows to finish the loop.

PrBacterio
Jul 19, 2000

hlfrk414 posted:

(...) The loop will catch a StopIteration exception at the end and then it knows to finish the loop(...)
Ughh... is it just me or is this REALLY ugly? I usually really like the way things work in Python but using exceptions as a regular control flow mechanism? Really?

hlfrk414
Dec 31, 2008

PrBacterio posted:

Ughh... is it just me or is this REALLY ugly? I usually really like the way things work in Python but using exceptions as a regular control flow mechanism? Really?

How would you propose they do it? Java's iterators have a hasNext method for all iterators, but since there is no guarantee that it will be called before next, so next calls it as well, breaking the DRY principle. Plus it implies all iterators will know if it has something next before it tries to get something next.

You should not use UNRELATED exceptions for regular flow control. That is why using IndexOutOfBoundsExceptions to know when to finish a loop is a horror, because it doesn't just mean that we finished looping. The StopInteration exception is ONLY used to stop a loop. It does not mean anything else. It allows a simple way to combine both getting an element and stopping iteration, since they are itimately tied anyways. Plus, it is an error to try to continue iteration past the end of a sequence anyways, so you'll need to throw an exception.

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"

Jo posted:

I do now. :saddowns:

Still, that means when calling the function I'd have to say
code:
  if thisThing instanceof dict:
    for i in thisThing.itervalues():
      i.doSomething()
  elif thisThing instanceof list:
    for i in thisThing:
      i.doSomething()
which, while an improvement, is still not quite as neutral as I'd like.

EDIT: For more clarity, I'm curious about accessing in a very duck-typed object friendly style the iterators for lists and dictionaries. If this isn't possible, it's not a big deal. Just want to know if I'm missing something obvious.

The point of "duck typing" is to treat an object according only to its methods, not to its actual type. Checking types explicitly is just about the opposite of what you ought to do.

The best way would be to have two functions, one for mappings (dicts, maps) and one for generic iterables (lists, sets, etc). If for some reason you're dead-set on handling unrelated interfaces in the same function, do something like this:

code:
try:
    itervalues = thisThing.itervalues
except AttributeError:
    values = thisThing
else:
    values = itervalues()

for value in values:
    value.doSomething()

Jo
Jan 24, 2005

:allears:
Soiled Meat

Janin posted:

The point of "duck typing" is to treat an object according only to its methods, not to its actual type. Checking types explicitly is just about the opposite of what you ought to do.

Exactly my point. I wanted to avoid explicitly doing an isinstance( thing, dict ) to keep it up to the duct-typing standard. Just curious about whether there was a method across both the list and dict(values).

Thank you very much for your help.

The Evan
Nov 29, 2004

Apple ][ Cash Money

PrBacterio posted:

Ughh... is it just me or is this REALLY ugly? I usually really like the way things work in Python but using exceptions as a regular control flow mechanism? Really?

it may not be "pythonic", although i couldn't say. personally, in the only real python app i've written, i use it for setting a booleans which then affects program flow, which isn't really directly controlling flow.

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...

PrBacterio posted:

Ughh... is it just me or is this REALLY ugly? I usually really like the way things work in Python but using exceptions as a regular control flow mechanism? Really?

I had the same reaction when that idiom was introduced. But I think this case gets a pass because the raise/catch is hidden. The warning about using exceptions for flow control is due to it obscuring the flow of execution but here (1) it's not obvious that exceptions are being used, that's just the implementation (2) the flow is obvious.

Habnabit
Dec 30, 2007

lift your skinny fists like
antennas in germany.

Jo posted:

What is the elegant/correct way to write a function that will iterate across both a list and a dictionary correctly.

I'd avoid this situation entirely. Why wouldn't you know whether you have a list or a dict? Sometimes trying to be too flexible results in more fragile code. It's also easy enough to just pass d.itervalues() to the function in the first place and make the function take an iterable.

ShizCakes posted:

The only thing that you guys haven't answered for me, and I am hoping someone can point me in the right direction, is that I'd really like to avoid the "handles all paths" style of web application. I think it's absolutely asinine that I should have to configure apache to lock a webapp down into a subdirectory. What I really long for is the PHP style of being able to drop a PHP file anywhere and have ONLY that php file be callable. If I want parameters, I have to pass them with ?. Is this possible?

EDIT: What I guess I am looking for is possibly a templating framework for Python? I am looking at them right now, but any pointers would be great.

Really, why is it that you're so against doing it the (typical) python way? Idioms don't always translate cleanly across languages, and this is definitely one of those things.

It's not like you have to write code for each template and each static file. Your web framework will take care of dispatching for you. Static files will be automatically served and adding actions to controllers is really simple if you're using a decent framework. Here's some real live code from a python web application I've been working on!

code:
class MainController(BaseController):
    def index(self):
        q = g.session.query(model.World)
        c.worlds = q.all()
        return render('/main/index.html')
    
    @require_auth(AUTH_ADMIN)
    def users(self):
        q = g.session.query(model.User)
        c.users = q.all()
        return render('/main/users.html')
See! No application logic in the templates; it's done in the action and then passed to the view.

tbradshaw
Jan 15, 2008

First one must nail at least two overdrive phrases and activate the tilt sensor to ROCK OUT!

ShizCakes posted:

What I really long for is the PHP style of being able to drop a PHP file anywhere and have ONLY that php file be callable. If I want parameters, I have to pass them with ?. Is this possible?

EDIT: What I guess I am looking for is possibly a templating framework for Python? I am looking at them right now, but any pointers would be great.

Not to be pedantic, but that "style" of development really sucks. :) Even major php applications drop the "multiple entry points, multiple exit points" style and do something much more similar to what you're seeing with python web development. (Which is really just solid MVC style architecture.)

As Habnabit suggests, really, you just want to embrace it. You're not going to find an elegant solution to do things like PHP (or old ASP) where you just have templates and put your program logic in them when needed because it's a very bad development practice and not even advanced PHP developers use it.

As far as templating packages, I would humbly suggest Genshi. It's not the fastest, but it's extremely good at getting things Right.

Sylink
Apr 17, 2004

I've been doing project euler in python and I can't wrap my brain around this problem.

http://projecteuler.net/index.php?section=problems&id=31

I know it can be recursive somehow but I just can't get it.

Can anyone explain a simple version of it using a smaller set perhaps?

Sylink
Apr 17, 2004

Also, are there any 'better' versions of the python IDLE/console that can handle writing very large lists and such without becoming very non-responsive/crashing.

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

Sylink posted:

Also, are there any 'better' versions of the python IDLE/console that can handle writing very large lists and such without becoming very non-responsive/crashing.

I've pasted megabyte-sized lists into the regular python console without a problem. But have you tried IPython?

Sylink
Apr 17, 2004

I have tried it, didn't really like it. I'm on windows and the standard interactive mode seems to poo poo itself if I have lists with tens of thousands of entries which seems trivial given how little memory it takes up and on modern processors.

EDIT: Ok I just tried it from MSDOS prompt/cmd.exe and its a lot smoother. Must be the GUI thing taking a poo poo.

Another question, on Windows, is there a way to open a command line in a directory then run a .py and have it end in interactive mode so I can check variables and whatnot for testing?

EDIT2:I got it, had to set path variables and what not, python -i etc.

Sylink fucked around with this message at 01:37 on May 8, 2009

Not an Anthem
Apr 28, 2003

I'm a fucking pain machine and if you even touch my fucking car I WILL FUCKING DESTROY YOU.
xposting from short questions that dont deserve their thread:

I'm in a basic mathematical computer science course and finishing up a project on sorting (bubble sort, better bubble, quick sort). We were given pseudocode that would work perfectly when translated, however it doesn't seem to. We're supposed to keep the sort algorithms in a seperate module and call them from the first module's main function.

http://www.chicagoburning.com/mp4/sort.py

Can anyone tell me what I'm doing wrong? Its not sorting the list I have set up to test it in the main function.

The other files in the directory are the main program and the explanation. I'm almost positive the main program works 100% and my hiccup is just the sorting.

tripwire
Nov 19, 2004

        ghost flow

Not an Anthem posted:

xposting from short questions that dont deserve their thread:

I'm in a basic mathematical computer science course and finishing up a project on sorting (bubble sort, better bubble, quick sort). We were given pseudocode that would work perfectly when translated, however it doesn't seem to. We're supposed to keep the sort algorithms in a seperate module and call them from the first module's main function.

http://www.chicagoburning.com/mp4/sort.py

Can anyone tell me what I'm doing wrong? Its not sorting the list I have set up to test it in the main function.

The other files in the directory are the main program and the explanation. I'm almost positive the main program works 100% and my hiccup is just the sorting.

When you call bub_sort1(L,len(L)) its working on a copy of your data and not returning anything. If you want to have a function gently caress around with global variables then declare them outside of the main function block. Alternatively, have the bub_sort function return a new sorted version of the list that was given to it; if you give it a list of tuples to sort for example, it doesn't make sense to try and shuffle them in place because tuples are immutable. Far better for you to rewrite that using code that would return a new sorted sequence matching whatever sequence type was given to it.

tripwire fucked around with this message at 16:47 on May 8, 2009

Not an Anthem
Apr 28, 2003

I'm a fucking pain machine and if you even touch my fucking car I WILL FUCKING DESTROY YOU.
We're just using the sort functions to time how long it takes and comparing their big oh (bubsort is n^2, qsort is nlogn), we dont need the sorted lists.

Sylink
Apr 17, 2004

Returning the list is arguably part of the time, but also add the time module so you can time it.

code:

from time time import *

start = time()

***
STUFF

****

finish = time()

print finish - start 

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

Quick question:

I'm working on some kernel stuff for AndroidOS for the summer, and the git checkout requires this Python wrapper program. When I try to run it, I get

code:
ntaylor$ repo init -u git://android.git.kernel.org/platform/manifest.git
Traceback (most recent call last):
  File "/Users/nathantaylor/bin/repo", line 91, in <module>
    import readline
  File "/Library/Python/2.5/site-packages/readline-2.5.1-py2.5-macosx-10.5-i386.egg/readline.py", line 5, in <module>
    del __bootstrap__, __loader__
  File "build/bdist.macosx-10.5-i386/egg/pyreadline/__init__.py", line 9, in <module>
  File "build/bdist.macosx-10.5-i386/egg/pyreadline/clipboard/__init__.py", line 12, in <module>
  File "build/bdist.macosx-10.5-i386/egg/pyreadline/clipboard/win32_clipboard.py", line 36, in <module>
  File "build/bdist.macosx-10.5-i386/egg/pyreadline/keysyms/__init__.py", line 20, in <module>
ImportError: ('Could not import keysym for local pythonversion', ImportError('cannot import name windll',))
Googling suggests that this is an issue with NumPy (which I have installed), but offers no suggestion for how to fix it. I tried installing GNU Readline from ports but that didn't fix anything. Hell, I don't even know where any of this crap gets installed to, so I can't remove this module by hand if I thought that was the solution. Any tips?

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...

Dijkstracula posted:

I'm working on some kernel stuff for AndroidOS for the summer, and the git checkout requires this Python wrapper program. When I try to run it, I get ...

Don't see anything to do with numpy there. Could it be that you are on a Mac and the script is trying to use Windows functions? That looks a bit weird there.

The readline on OSX can be problematic. Failing anything else, reinstalling that may be fruitful.

m0nk3yz
Mar 13, 2002

Behold the power of cheese!

Dijkstracula posted:

Quick question:

I'm working on some kernel stuff for AndroidOS for the summer, and the git checkout requires this Python wrapper program. When I try to run it, I get

code:
ntaylor$ repo init -u git://android.git.kernel.org/platform/manifest.git
Traceback (most recent call last):
  File "/Users/nathantaylor/bin/repo", line 91, in <module>
    import readline
  File "/Library/Python/2.5/site-packages/readline-2.5.1-py2.5-macosx-10.5-i386.egg/readline.py", line 5, in <module>
    del __bootstrap__, __loader__
  File "build/bdist.macosx-10.5-i386/egg/pyreadline/__init__.py", line 9, in <module>
  File "build/bdist.macosx-10.5-i386/egg/pyreadline/clipboard/__init__.py", line 12, in <module>
  File "build/bdist.macosx-10.5-i386/egg/pyreadline/clipboard/win32_clipboard.py", line 36, in <module>
  File "build/bdist.macosx-10.5-i386/egg/pyreadline/keysyms/__init__.py", line 20, in <module>
ImportError: ('Could not import keysym for local pythonversion', ImportError('cannot import name windll',))
Googling suggests that this is an issue with NumPy (which I have installed), but offers no suggestion for how to fix it. I tried installing GNU Readline from ports but that didn't fix anything. Hell, I don't even know where any of this crap gets installed to, so I can't remove this module by hand if I thought that was the solution. Any tips?

Remove your pyreadline, it's a windows-only module. From http://www.google.com/search?hl=en&...Search&aq=f&oq=

NadaTooma
Aug 24, 2004

The good thing is that everyone around you has more critical failures in combat, the bad thing is - so do you!

Sylink posted:

Returning the list is arguably part of the time, but also add the time module so you can time it.

Or better yet, use the "profile" module...

code:
def stuff():
    total = 0
    for i in xrange(1000000):
        total += i
    return total

import profile
profile.run("stuff()")

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

Thanks for the responses.

m0nk3yz posted:

Remove your pyreadline, it's a windows-only module. From http://www.google.com/search?hl=en&...Search&aq=f&oq=
Yeah, I should have been more clear in that that was the advice I found online, but I'm not sure where pynumline is hidden so I can't blow it away. Where is it hiding?

Sylink
Apr 17, 2004

Hey I didn't know about the profile module, thanks.

Sylink
Apr 17, 2004

Can someone explain parsing with elementtree to me, it makes no sense and the effbot stuff seems to all be about making xml, I just want to get information.

Like if I have an element <title>, how do I get the actual content between the tags?

ahobday
Apr 19, 2007

Sylink posted:

Can someone explain parsing with elementtree to me, it makes no sense and the effbot stuff seems to all be about making xml, I just want to get information.

Like if I have an element <title>, how do I get the actual content between the tags?

I've just done this for my university project.

code:
titlecontent = tree.find("title").text
But this'll only work if your "title" elements are direct sub-elements of your root element, I believe.

XML would be so much easier to parse if you could just parse the XML in and access it this way:

code:
<root>
  <element>
    <subelement>
    Hey there!
    </subelement>
  </element>
</root>

>>> print(root.element.subelement)
Hey there!

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Sylink posted:

Can someone explain parsing with elementtree to me, it makes no sense and the effbot stuff seems to all be about making xml, I just want to get information.

Like if I have an element <title>, how do I get the actual content between the tags?

I have no experience with elementtree, but you may want to look at BeautifulSoup.

tbradshaw
Jan 15, 2008

First one must nail at least two overdrive phrases and activate the tilt sensor to ROCK OUT!

Centipeed posted:

But this'll only work if your "title" elements are direct sub-elements of your root element, I believe.

You focused on the wrong part of the example. The important part of that example is the ".text" property that retrieves the contained text just as you want it. Find it however you want.

Centipeed posted:

XML would be so much easier to parse if you could just parse the XML in and access it this way:

That breaks because nested tags are as equally important as the text. Most importantly, in the base case tags hold other tags and *not* text. But, it's true, it would be easier for you if they ignored the breadth of XML and just focused on the small part that you're using. ;D

ahobday
Apr 19, 2007

tbradshaw posted:

That breaks because nested tags are as equally important as the text. Most importantly, in the base case tags hold other tags and *not* text. But, it's true, it would be easier for you if they ignored the breadth of XML and just focused on the small part that you're using. ;D

Is it wrong of me to think that "root.element1.element2" is more elegant than "root.find("element1").find("element2").text"? Obviously they've done it the second way because it wouldn't work my way, as you say. I just wish it were more intuitive.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

Centipeed posted:

Is it wrong of me to think that "root.element1.element2" is more elegant than "root.find("element1").find("element2").text"? Obviously they've done it the second way because it wouldn't work my way, as you say. I just wish it were more intuitive.

Warning: I don't know python, I'm in this thread to learn about it.

Seems like you could write code for something like this:
root.findByString("element1.element2.element3")

or at least a function like:
findElementByString(root, "element1.element2.element3")


The function body is: (horrible pseudopseudocode follows)
code:
set e = root
while (still string tokens left)
{
 s = new string token  [easy in python right?]
 e = e.find("token")
}
return e

taqueso fucked around with this message at 18:03 on May 9, 2009

sw-itch
Apr 6, 2008

Centipeed posted:

Is it wrong of me to think that "root.element1.element2" is more elegant than "root.find("element1").find("element2").text"? Obviously they've done it the second way because it wouldn't work my way, as you say. I just wish it were more intuitive.

A wrapper for this was actually posted yesterday on http://planet.python.org , maybe they read this thread.

quote:

As you know, ElementTree's interface is boring and most time you don't need all these findalls and attribs. 80% of code requires simple operation like: "access to child B and get it's attribute C". So, why to type root.find('B').attrib['C'], when you can use simple construction like root.B.C? To accomplish this task, I wrote a simple wrapper for ElementTree.
code:
#########################################################
# Title: Simple ElementTree accessor
# Author: Alexander Artemenko <svetlyak.40wt>
# Site: [url]http://aartemenko.com[/url]
# License: New BSD License
#########################################################

class Accessor(object):
    """Easy to use ElementTree accessor."""

    def __init__(self, xml):
        self.xml = xml

    def __repr__(self):
        return '<element>' % self.xml.tag

    def __len__(self):
        return self.xml.__len__()

    def __iter__(self):
        return iter(self.xml)

    def __getattribute__(self, name):
        """
        >>> from xml.etree import ElementTree as ET
        >>> xml = ET.fromstring('<a b="blah"><c id="1"></c><c id="2"><d>Hello</d></c></a>')
        >>> a = Accessor(xml)
        >>> a.b
        'blah'
        >>> a.c
        [</element><element c="c">, </element><element c="c">]
        >>> a.c[1].d
        </element><element d="d">
        >>> a.c[1].d.text
        'Hello'
        >>> ET.tostring(a)
        '<a b="blah"><c id="1"></c><c id="2"><d>Hello</d></c></a>'
        """
        if name == 'xml':
            return object.__getattribute__(self, name)

        elements = self.xml.findall(name)
        l = len(elements)
        if l == 1:
            return Accessor(elements[0])
        elif l > 1:
            return map(Accessor, elements)

        if self.xml.attrib.has_key(name):
            return self.xml.attrib[name]

        if hasattr(self.xml, name):
            return getattr(self.xml, name)
        raise AttributeError
http://aartemenko.com/texts/elementtree-accessor/

Adbot
ADBOT LOVES YOU

Sylink
Apr 17, 2004

It just seems like every time I want to parse xml its completely non-intuitive and voodoo. Not to mention they don't have practical examples most of the time it seems. :(

  • Locked thread