469,643 Members | 1,310 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,643 developers. It's quick & easy.

Simulating call-by-reference

I'm tidying up some code. Basically, the code runs a bunch of
regexp-searches (> 10) on a text and stores the match in a different variable.

Like this:

re1 = r' ..(.*).. '
re2 = r' .... '
re3 = r' .(.*).. '
...
m = re.search(re1, data)
if m:
myclass.bar = m.group(1)

m = re.search(re2, data)
if m:
myclass.foo = m.group(1)

m = re.search(re3, data)
if m:
myclass.baz = m.group(1)
While this code works, it's not very good looking.

What I want is to rewrite it to something like this:

l = [ (re1, myclass.bar),
(re2, myclass.foo),
(re3, myclass.baz),
]

for (x,y) in l:
m = re.search(x, y)
if m:
y = m.group(1)

But since Python doesn't work that way, that idea is doomed. What I'm
looking for are other (better) ways or pointers to accomplish this task of
cleanup.
--
Sincerely, | http://bos.hack.org/cv/
Rikard Bosnjakovic | Code chef - will cook for food
------------------------------------------------------------------------
Nov 22 '05 #1
10 1357

Rikard Bosnjakovic wrote:
I'm tidying up some code. Basically, the code runs a bunch of
regexp-searches (> 10) on a text and stores the match in a different variable.

Like this:

re1 = r' ..(.*).. '
re2 = r' .... '
re3 = r' .(.*).. '
...
m = re.search(re1, data)
if m:
myclass.bar = m.group(1)

m = re.search(re2, data)
if m:
myclass.foo = m.group(1)

m = re.search(re3, data)
if m:
myclass.baz = m.group(1)
While this code works, it's not very good looking.

What I want is to rewrite it to something like this:

l = [ (re1, myclass.bar),
(re2, myclass.foo),
(re3, myclass.baz),
]

for (x,y) in l:
m = re.search(x, y)
if m:
y = m.group(1)

But since Python doesn't work that way, that idea is doomed. What I'm
looking for are other (better) ways or pointers to accomplish this task of
cleanup.
-----------------


I believe you can use the "setattr/getattr" call

l = [ (re1, myclass, "bar") ]

for x,y,z in l:
m = re.search(x,getattr(y,z))
if m: setattr(y,z,m.group(1))

Nov 22 '05 #2

Rikard Bosnjakovic wrote:
I'm tidying up some code. Basically, the code runs a bunch of
regexp-searches (> 10) on a text and stores the match in a different variable.

Like this:

re1 = r' ..(.*).. '
re2 = r' .... '
re3 = r' .(.*).. '
...
m = re.search(re1, data)
if m:
myclass.bar = m.group(1)

m = re.search(re2, data)
if m:
myclass.foo = m.group(1)

m = re.search(re3, data)
if m:
myclass.baz = m.group(1)
While this code works, it's not very good looking.

What I want is to rewrite it to something like this:

l = [ (re1, myclass.bar),
(re2, myclass.foo),
(re3, myclass.baz),
]

for (x,y) in l:
m = re.search(x, y)
if m:
y = m.group(1)

But since Python doesn't work that way, that idea is doomed. What I'm
looking for are other (better) ways or pointers to accomplish this task of
cleanup.
-----------------


I believe you can use the "setattr/getattr" call

l = [ (re1, myclass, "bar") ]

for x,y,z in l:
m = re.search(x,getattr(y,z))
if m: setattr(y,z,m.group(1))

Nov 22 '05 #3
On Thu, 17 Nov 2005 10:03:50 GMT,
Rikard Bosnjakovic <bo*@REMOVETHIShack.org> wrote:
What I want is to rewrite it to something like this: l = [ (re1, myclass.bar),
(re2, myclass.foo),
(re3, myclass.baz),
] for (x,y) in l:
m = re.search(x, y)
if m:
y = m.group(1) But since Python doesn't work that way, that idea is doomed. What I'm
looking for are other (better) ways or pointers to accomplish this
task of cleanup.


Put the results into a dictionary (untested code follows!):

l = [ (re1, 'bar'),
(re2, 'foo'),
(re3, 'baz'),
]
results = {}
for (regexp, key) in l:
m = re.search(regexp, data)
if m:
results[key] = m.group(1)

Now you can access the results as results['foo'], etc. Or look up the
Borg pattern in the ASPN cookbook and you can access the results as
results.foo, etc.

Regards,
Dan

--
Dan Sommers
<http://www.tombstonezero.net/dan/>
Nov 22 '05 #4
On Thu, 17 Nov 2005 10:03:50 GMT,
Rikard Bosnjakovic <bo*@REMOVETHIShack.org> wrote:
What I want is to rewrite it to something like this: l = [ (re1, myclass.bar),
(re2, myclass.foo),
(re3, myclass.baz),
] for (x,y) in l:
m = re.search(x, y)
if m:
y = m.group(1) But since Python doesn't work that way, that idea is doomed. What I'm
looking for are other (better) ways or pointers to accomplish this
task of cleanup.


Put the results into a dictionary (untested code follows!):

l = [ (re1, 'bar'),
(re2, 'foo'),
(re3, 'baz'),
]
results = {}
for (regexp, key) in l:
m = re.search(regexp, data)
if m:
results[key] = m.group(1)

Now you can access the results as results['foo'], etc. Or look up the
Borg pattern in the ASPN cookbook and you can access the results as
results.foo, etc.

Regards,
Dan

--
Dan Sommers
<http://www.tombstonezero.net/dan/>
Nov 22 '05 #5
Dan Sommers <me@privacy.net> wrote:
...
Put the results into a dictionary (untested code follows!):

l = [ (re1, 'bar'),
(re2, 'foo'),
(re3, 'baz'),
]
results = {}
for (regexp, key) in l:
m = re.search(regexp, data)
if m:
results[key] = m.group(1)

Now you can access the results as results['foo'], etc. Or look up the
Borg pattern in the ASPN cookbook and you can access the results as
results.foo, etc.


I think you mean the Bunch idiom, rather than the Borg one (which has to
do with having instances of the same class share state).

Personally, I would rather pass myvar as well as the attribute names,
and set them with setattr, as I see some others already suggested.
Alex
Nov 22 '05 #6
On Thu, 17 Nov 2005 12:31:08 -0800,
al***@mail.comcast.net (Alex Martelli) wrote:
Dan Sommers <me@privacy.net> wrote:
...
Put the results into a dictionary (untested code follows!):
[ example code snipped ]
Now you can access the results as results['foo'], etc. Or look up
the Borg pattern in the ASPN cookbook and you can access the results
as results.foo, etc.
I think you mean the Bunch idiom, rather than the Borg one (which has to
do with having instances of the same class share state).
Oops. <sheepish grin>

You're right.

Sorry.
Personally, I would rather pass myvar as well as the attribute names,
and set them with setattr, as I see some others already suggested.


I lose track of things too easily that way. YMMV.

Regards,
Dan

--
Dan Sommers
<http://www.tombstonezero.net/dan/>
Nov 22 '05 #7
Dan Sommers <me@privacy.net> wrote:
...
Put the results into a dictionary (untested code follows!):

l = [ (re1, 'bar'),
(re2, 'foo'),
(re3, 'baz'),
]
results = {}
for (regexp, key) in l:
m = re.search(regexp, data)
if m:
results[key] = m.group(1)

Now you can access the results as results['foo'], etc. Or look up the
Borg pattern in the ASPN cookbook and you can access the results as
results.foo, etc.


I think you mean the Bunch idiom, rather than the Borg one (which has to
do with having instances of the same class share state).

Personally, I would rather pass myvar as well as the attribute names,
and set them with setattr, as I see some others already suggested.
Alex
Nov 22 '05 #8
On Thu, 17 Nov 2005 12:31:08 -0800,
al***@mail.comcast.net (Alex Martelli) wrote:
Dan Sommers <me@privacy.net> wrote:
...
Put the results into a dictionary (untested code follows!):
[ example code snipped ]
Now you can access the results as results['foo'], etc. Or look up
the Borg pattern in the ASPN cookbook and you can access the results
as results.foo, etc.
I think you mean the Bunch idiom, rather than the Borg one (which has to
do with having instances of the same class share state).
Oops. <sheepish grin>

You're right.

Sorry.
Personally, I would rather pass myvar as well as the attribute names,
and set them with setattr, as I see some others already suggested.


I lose track of things too easily that way. YMMV.

Regards,
Dan

--
Dan Sommers
<http://www.tombstonezero.net/dan/>
Nov 22 '05 #9
On Thu, 17 Nov 2005 10:03:50 GMT, Rikard Bosnjakovic <bo*@REMOVETHIShack.org> wrote:
I'm tidying up some code. Basically, the code runs a bunch of
regexp-searches (> 10) on a text and stores the match in a different variable.

Like this:

re1 = r' ..(.*).. '
re2 = r' .... '
re3 = r' .(.*).. '
...
m = re.search(re1, data)
if m:
myclass.bar = m.group(1)

m = re.search(re2, data)
if m:
myclass.foo = m.group(1)

m = re.search(re3, data)
if m:
myclass.baz = m.group(1)
While this code works, it's not very good looking.

What I want is to rewrite it to something like this:

l = [ (re1, myclass.bar),
(re2, myclass.foo),
(re3, myclass.baz),
]

for (x,y) in l:
m = re.search(x, y)
if m:
y = m.group(1)

But since Python doesn't work that way, that idea is doomed. What I'm
looking for are other (better) ways or pointers to accomplish this task of
cleanup.

You could tag your regexs with the foo bar baz names, and pre-compile them.
Then you could do something like
import re
re1 = re.compile(r'(?P<bar>\d+)') # find an int
re2 = re.compile(r'(?P<foo>[A-Z]+)') # find a cap seq
re3 = re.compile(r'(?P<baz>[a-z]+)') # find a lower case seq

data = 'abc12 34CAPS lowercase'

class myclass(object): pass # ?? ... class myotherclass(object): pass # ??? ... L = [ (re1, myclass), ... (re2, myclass),
... (re3, myotherclass),
... ] for (rx, cls) in L: ... m = rx.search(data)
... if m:
... setattr(cls, *m.groupdict().items()[0])
... myclass.bar '12' myclass.foo 'CAPS' myotherclass.baz 'abc'

Of course, this is only finding a single group, so this specific code
might not work for other searches you might like to do. Also, if you don't
need an alternate myotherclass, DRY says don't repeat it in L. I.e., you
could write (spelling myclass more conventionally)
class MyClass(object): pass # ?? ... L = (re1, re2, re3)
for (rx) in L: ... m = rx.search(data)
... if m: setattr(MyClass, *m.groupdict().items()[0])
... for k,v in MyClass.__dict__.items(): print '%15s: %r'%(k,v) ...
__module__: '__main__'
bar: '12'
baz: 'abc'
__dict__: <attribute '__dict__' of 'MyClass' objects>
foo: 'CAPS'
__weakref__: <attribute '__weakref__' of 'MyClass' objects>
__doc__: None for it in (it for it in MyClass.__dict__.items() if not it[0].startswith('_')): print '%15s: %r'%it

...
bar: '12'
baz: 'abc'
foo: 'CAPS'

The
setattr(MyClass, *m.groupdict().items()[0])

just makes an assignment of whatever comes out to be the first of name-tagged
matches (of which there has to at least one here also). If you want several name-tagged
matches in a single regex, you could do that and do a setattr for each item in m.groubdict().items().

What else you can do is only limited by your imagination ;-)

Regards,
Bengt Richter
Nov 22 '05 #10
On Thu, 17 Nov 2005 10:03:50 GMT, Rikard Bosnjakovic <bo*@REMOVETHIShack.org> wrote:
I'm tidying up some code. Basically, the code runs a bunch of
regexp-searches (> 10) on a text and stores the match in a different variable.

Like this:

re1 = r' ..(.*).. '
re2 = r' .... '
re3 = r' .(.*).. '
...
m = re.search(re1, data)
if m:
myclass.bar = m.group(1)

m = re.search(re2, data)
if m:
myclass.foo = m.group(1)

m = re.search(re3, data)
if m:
myclass.baz = m.group(1)
While this code works, it's not very good looking.

What I want is to rewrite it to something like this:

l = [ (re1, myclass.bar),
(re2, myclass.foo),
(re3, myclass.baz),
]

for (x,y) in l:
m = re.search(x, y)
if m:
y = m.group(1)

But since Python doesn't work that way, that idea is doomed. What I'm
looking for are other (better) ways or pointers to accomplish this task of
cleanup.

You could tag your regexs with the foo bar baz names, and pre-compile them.
Then you could do something like
import re
re1 = re.compile(r'(?P<bar>\d+)') # find an int
re2 = re.compile(r'(?P<foo>[A-Z]+)') # find a cap seq
re3 = re.compile(r'(?P<baz>[a-z]+)') # find a lower case seq

data = 'abc12 34CAPS lowercase'

class myclass(object): pass # ?? ... class myotherclass(object): pass # ??? ... L = [ (re1, myclass), ... (re2, myclass),
... (re3, myotherclass),
... ] for (rx, cls) in L: ... m = rx.search(data)
... if m:
... setattr(cls, *m.groupdict().items()[0])
... myclass.bar '12' myclass.foo 'CAPS' myotherclass.baz 'abc'

Of course, this is only finding a single group, so this specific code
might not work for other searches you might like to do. Also, if you don't
need an alternate myotherclass, DRY says don't repeat it in L. I.e., you
could write (spelling myclass more conventionally)
class MyClass(object): pass # ?? ... L = (re1, re2, re3)
for (rx) in L: ... m = rx.search(data)
... if m: setattr(MyClass, *m.groupdict().items()[0])
... for k,v in MyClass.__dict__.items(): print '%15s: %r'%(k,v) ...
__module__: '__main__'
bar: '12'
baz: 'abc'
__dict__: <attribute '__dict__' of 'MyClass' objects>
foo: 'CAPS'
__weakref__: <attribute '__weakref__' of 'MyClass' objects>
__doc__: None for it in (it for it in MyClass.__dict__.items() if not it[0].startswith('_')): print '%15s: %r'%it

...
bar: '12'
baz: 'abc'
foo: 'CAPS'

The
setattr(MyClass, *m.groupdict().items()[0])

just makes an assignment of whatever comes out to be the first of name-tagged
matches (of which there has to at least one here also). If you want several name-tagged
matches in a single regex, you could do that and do a setattr for each item in m.groubdict().items().

What else you can do is only limited by your imagination ;-)

Regards,
Bengt Richter
Nov 22 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by jimif_fr | last post: by
12 posts views Thread by cppaddict | last post: by
47 posts views Thread by Lauren Quantrell | last post: by
3 posts views Thread by Doug Eleveld | last post: by
6 posts views Thread by bwahahahaha | last post: by
6 posts views Thread by Timo | last post: by
8 posts views Thread by John Dann | last post: by
reply views Thread by Andrew Teece | last post: by
4 posts views Thread by Bill Pursell | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.