By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,629 Members | 1,222 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,629 IT Pros & Developers. It's quick & easy.

namespace dictionaries ok?

P: n/a

Hi, I found the following to be a useful way to access arguments after
they are passed to a function that collects them with **kwds.
class namespace(dict):
def __getattr__(self, name):
return self.__getitem__(name)
def __setattr__(self, name, value):
self.__setitem__(name, value)
def __delattr__(self, name):
self.__delitem__(name)

def foo(**kwds):
kwds = namespace(kwds)
print kwds.color, kwds.size, kwds.shape etc....

foo( color='red', size='large', shape='ball', .... etc..)
It just seems awkward to have to use "string keys" in this situation.
This is easy and still retains the dictionary so it can be modified and
passed to another function or method as kwds again.

Any thoughts? Any better way to do this?

Cheers, Ron

Oct 25 '05 #1
Share this Question
Share on Google+
27 Replies


P: n/a
Here it goes with a little less overhead:
py> class namespace:
.... def __init__(self, adict):
.... self.__dict__.update(adict)
....
py> n = namespace({'bob':1, 'carol':2, 'ted':3, 'alice':4})
py> n.bob
1
py> n.ted
3

James

On Monday 24 October 2005 19:06, Ron Adam wrote:
Hi, I found the following to be a useful way to access arguments after
they are passed to a function that collects them with **kwds.
class namespace(dict):
def __getattr__(self, name):
return self.__getitem__(name)
def __setattr__(self, name, value):
self.__setitem__(name, value)
def __delattr__(self, name):
self.__delitem__(name)

def foo(**kwds):
kwds = namespace(kwds)
print kwds.color, kwds.size, kwds.shape etc....

foo( color='red', size='large', shape='ball', .... etc..)
It just seems awkward to have to use "string keys" in this situation.
This is easy and still retains the dictionary so it can be modified and
passed to another function or method as kwds again.

Any thoughts? Any better way to do this?

Cheers, Ron


--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Oct 25 '05 #2

P: n/a

Yes!

I do this a lot when i have deeply nested function calls
a->b->c->d->e
and need to pass args to the deep function without changing the
middle functions.

In this situation I think i would prefer this variation:

class Context(dict):
def __init__(self,**kwds):
dict.__init__(self,kwds)
def __getattr__(self, name):
return self.__getitem__(name)
def __setattr__(self, name, value):
self.__setitem__(name, value)
def __delattr__(self, name):
self.__delitem__(name)

def foo(ctx):
print ctx.color, ctx.size, ctx.shape

foo( Context(color='red', size='large', shape='ball') )
This is looking like foo should be a method of Context now,
but in my situation foo is already a method of another class.

Simon.

Oct 25 '05 #3

P: n/a
James Stroud wrote:
Here it goes with a little less overhead:
py> class namespace:
... def __init__(self, adict):
... self.__dict__.update(adict)
...
py> n = namespace({'bob':1, 'carol':2, 'ted':3, 'alice':4})
py> n.bob
1
py> n.ted
3

James
But it's not a dictionary anymore so you can't use it in the same places
you would use a dictionary.

foo(**n)

Would raise an error.

So I couldn't do:

def foo(**kwds):
kwds = namespace(kwds)
kwds.bob = 3
kwds.alice = 5
...
bar(**kwds) #<--- do something with changed items

Ron

On Monday 24 October 2005 19:06, Ron Adam wrote:
Hi, I found the following to be a useful way to access arguments after
they are passed to a function that collects them with **kwds.
class namespace(dict):
def __getattr__(self, name):
return self.__getitem__(name)
def __setattr__(self, name, value):
self.__setitem__(name, value)
def __delattr__(self, name):
self.__delitem__(name)

def foo(**kwds):
kwds = namespace(kwds)
print kwds.color, kwds.size, kwds.shape etc....

foo( color='red', size='large', shape='ball', .... etc..)
It just seems awkward to have to use "string keys" in this situation.
This is easy and still retains the dictionary so it can be modified and
passed to another function or method as kwds again.

Any thoughts? Any better way to do this?

Cheers, Ron


Oct 25 '05 #4

P: n/a
Simon Burton wrote:
Yes!

I do this a lot when i have deeply nested function calls
a->b->c->d->e
and need to pass args to the deep function without changing the
middle functions.
Yes, :-) Which is something like what I'm doing also. Get the
dictionary, modify it or validate it somehow, then pass it on. I also
find that when I'm passing variables as keywords,

foo(name=name, address=address, city=city)

I really don't want (or like) to have to access the names with
dictionary key as *strings* in the function that is called and collects
them in a single object.

In this situation I think i would prefer this variation:

class Context(dict):
def __init__(self,**kwds):
dict.__init__(self,kwds)
def __getattr__(self, name):
return self.__getitem__(name)
def __setattr__(self, name, value):
self.__setitem__(name, value)
def __delattr__(self, name):
self.__delitem__(name)

def foo(ctx):
print ctx.color, ctx.size, ctx.shape

foo( Context(color='red', size='large', shape='ball') )
This is looking like foo should be a method of Context now,
but in my situation foo is already a method of another class.

Simon.


I didn't see what you were referring to at first. But yes, I see the
similarity.

Cheers,
Ron


Oct 25 '05 #5

P: n/a
Oops. Answered before I finished reading the question.

James

On Monday 24 October 2005 19:53, Ron Adam wrote:
James Stroud wrote:
Here it goes with a little less overhead:
py> class namespace:
... def __init__(self, adict):
... self.__dict__.update(adict)
...
py> n = namespace({'bob':1, 'carol':2, 'ted':3, 'alice':4})
py> n.bob
1
py> n.ted
3

James


But it's not a dictionary anymore so you can't use it in the same places
you would use a dictionary.

foo(**n)

Would raise an error.

So I couldn't do:

def foo(**kwds):
kwds = namespace(kwds)
kwds.bob = 3
kwds.alice = 5
...
bar(**kwds) #<--- do something with changed items

Ron
On Monday 24 October 2005 19:06, Ron Adam wrote:
Hi, I found the following to be a useful way to access arguments after
they are passed to a function that collects them with **kwds.
class namespace(dict):
def __getattr__(self, name):
return self.__getitem__(name)
def __setattr__(self, name, value):
self.__setitem__(name, value)
def __delattr__(self, name):
self.__delitem__(name)

def foo(**kwds):
kwds = namespace(kwds)
print kwds.color, kwds.size, kwds.shape etc....

foo( color='red', size='large', shape='ball', .... etc..)
It just seems awkward to have to use "string keys" in this situation.
This is easy and still retains the dictionary so it can be modified and
passed to another function or method as kwds again.

Any thoughts? Any better way to do this?

Cheers, Ron


--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Oct 25 '05 #6

P: n/a
On Tue, 25 Oct 2005 03:10:17 GMT, Ron Adam <rr*@ronadam.com> wrote:
Simon Burton wrote:
Yes!

I do this a lot when i have deeply nested function calls
a->b->c->d->e
and need to pass args to the deep function without changing the
middle functions.


Yes, :-) Which is something like what I'm doing also. Get the
dictionary, modify it or validate it somehow, then pass it on. I also
find that when I'm passing variables as keywords,

foo(name=name, address=address, city=city)

I really don't want (or like) to have to access the names with
dictionary key as *strings* in the function that is called and collects
them in a single object.

In this situation I think i would prefer this variation:

class Context(dict):
def __init__(self,**kwds):
dict.__init__(self,kwds)
def __getattr__(self, name):
return self.__getitem__(name)
def __setattr__(self, name, value):
self.__setitem__(name, value)
def __delattr__(self, name):
self.__delitem__(name)

def foo(ctx):
print ctx.color, ctx.size, ctx.shape

foo( Context(color='red', size='large', shape='ball') )
This is looking like foo should be a method of Context now,
but in my situation foo is already a method of another class.
Or maybe just add a __repr__ method, if you want to see a readable
representation (e.g., see below).
Simon.


I didn't see what you were referring to at first. But yes, I see the
similarity.
class Context(dict): ... def __init__(self,**kwds):
... dict.__init__(self,kwds)
... def __getattr__(self, name):
... return self.__getitem__(name)
... def __setattr__(self, name, value):
... self.__setitem__(name, value)
... def __delattr__(self, name):
... self.__delitem__(name)
... def __repr__(self):
... return 'Context(%s)' % ', '.join('%s=%r'% t for t in sorted(self.items()))
... print Context(color='red', size='large', shape='ball') Context(color='red', shape='ball', size='large') ctx = Context(color='red', size='large', shape='ball')
print ctx Context(color='red', shape='ball', size='large') ctx Context(color='red', shape='ball', size='large') ctx.color

'red'

Regards,
Bengt Richter
Oct 25 '05 #7

P: n/a
James Stroud wrote:
Oops. Answered before I finished reading the question.

James
Well, the one bad side effect (or feature depending on the
circumstance), is it makes a copy. I wonder if there is a way to modify
the dictionary in place with a function to do the same thing instead of
creating a new object?

Cheers,
Ron

On Monday 24 October 2005 19:53, Ron Adam wrote:
James Stroud wrote:
Here it goes with a little less overhead:
py> class namespace:
... def __init__(self, adict):
... self.__dict__.update(adict)
...
py> n = namespace({'bob':1, 'carol':2, 'ted':3, 'alice':4})
py> n.bob
1
py> n.ted
3

James


But it's not a dictionary anymore so you can't use it in the same places
you would use a dictionary.

foo(**n)

Would raise an error.

So I couldn't do:

def foo(**kwds):
kwds = namespace(kwds)
kwds.bob = 3
kwds.alice = 5
...
bar(**kwds) #<--- do something with changed items

Ron

On Monday 24 October 2005 19:06, Ron Adam wrote:

Hi, I found the following to be a useful way to access arguments after
they are passed to a function that collects them with **kwds.
class namespace(dict):
def __getattr__(self, name):
return self.__getitem__(name)
def __setattr__(self, name, value):
self.__setitem__(name, value)
def __delattr__(self, name):
self.__delitem__(name)

def foo(**kwds):
kwds = namespace(kwds)
print kwds.color, kwds.size, kwds.shape etc....

foo( color='red', size='large', shape='ball', .... etc..)
It just seems awkward to have to use "string keys" in this situation.
This is easy and still retains the dictionary so it can be modified and
passed to another function or method as kwds again.

Any thoughts? Any better way to do this?

Cheers, Ron


Oct 25 '05 #8

P: n/a
James Stroud wrote:
Here it goes with a little less overhead:
py> class namespace:
... def __init__(self, adict):
... self.__dict__.update(adict)
...
py> n = namespace({'bob':1, 'carol':2, 'ted':3, 'alice':4})
py> n.bob
1
py> n.ted
3

James


How about...

class namespace(dict):
__getattr__ = dict.__getitem__
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
This seems to work, and eliminates the indirect method calls.

Cheers,
Ron

Oct 25 '05 #9

P: n/a
Simon Burton wrote:

Yes!

I do this a lot when i have deeply nested function calls
a->b->c->d->e
and need to pass args to the deep function without changing the
middle functions.


If you find yourself passing arguments to functions
just so they can in turn pass them on to other
functions, you probably shouldn't be using deeply
nested function calls and should be looking for another
program structure.
--
Steven.

Oct 25 '05 #10

P: n/a
Ron Adam wrote:
James Stroud wrote:
Here it goes with a little less overhead:

<example snipped>

But it's not a dictionary anymore so you can't use it in the same places
you would use a dictionary.

foo(**n)

Would raise an error.

So I couldn't do:

def foo(**kwds):
kwds = namespace(kwds)
kwds.bob = 3
kwds.alice = 5
...
bar(**kwds) #<--- do something with changed items

I agree with Steven D'Aprano's reply, but if you are set on it you could
try this:
class namespace(dict): def __init__(self, *args, **kw):
dict.__init__(self, *args, **kw)
self.__dict__ = self

n = namespace({'bob':1, 'carol':2, 'ted':3, 'alice':4})
n.bob 1 n.bob = 3
n['bob']

3

The big problem of course with this sort of approach is that you cannot
then safely use any of the methods of the underlying dict as they could be
masked by values.

P.S. James, *please* could you avoid top-quoting.
Oct 25 '05 #11

P: n/a
Duncan Booth wrote:
Ron Adam wrote:
James Stroud wrote:
Here it goes with a little less overhead:
<example snipped>
But it's not a dictionary anymore so you can't use it in the same places
you would use a dictionary.

foo(**n)

Would raise an error.

So I couldn't do:

def foo(**kwds):
kwds = namespace(kwds)
kwds.bob = 3
kwds.alice = 5
...
bar(**kwds) #<--- do something with changed items


I agree with Steven D'Aprano's reply, but if you are set on it you could
try this:

class namespace(dict):
def __init__(self, *args, **kw):
dict.__init__(self, *args, **kw)
self.__dict__ = self
n = namespace({'bob':1, 'carol':2, 'ted':3, 'alice':4})
n.bob
1
n.bob = 3
n['bob']


3

The big problem of course with this sort of approach is that you cannot
then safely use any of the methods of the underlying dict as they could be
masked by values.

P.S. James, *please* could you avoid top-quoting.


Or worse, the dictionary would become not functional depending on what
methods were masked.
And this approach reverses that, The dict values will be masked by the
methods, so the values can't effect the dictionary methods. But those
specific values are only retrievable with the standard dictionary notation.

class namespace(dict):
__getattr__ = dict.__getitem__
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__

n = namespace()
n.__getattr__ = 'yes' # doesn't mask __getattr__ method.

print n['__getattr__'] -> 'yes'

The value is there and __getattr__() still works. But n.__getattr__
returns the method not the value.

So is there a way to keep the functionality without loosing the methods?
BTW, I agree with Steven concerning data structures. This really isn't
a substitute for a data structure. Many keys will not work with this.

n.my name = 'Ron'
n.(1,2) = 25
n.John's = [ ... ]

The use case I'm thinking of is not as a shortcut for data structures,
but instead, as a way to keep names as names, and maintaining those
names in a group. Thus the namespace association.

def foo(**kwds):
kwds = namespace(kwds)
print kwds.name
print kwds.value
...

name = 'ron'
value = 25
foo( name=name, position=position )

Cheers,
Ron
Oct 25 '05 #12

P: n/a
On Tuesday 25 October 2005 00:31, Duncan Booth wrote:
P.S. James, *please* could you avoid top-quoting


Were it not for Steve Holden's providing me with a link off the list, I would
have never known to what it is you are referring. I have read some relevant
literature to find that this is more widely known as "top-posting". I'll go
with majority rules here, but I would like to say that my lack of
"netiquette" in this matter comes from practicality and not malice. I have
read many a letter both in-line quoted and/or top-posted and have never
really made a distinction between the two. Both styles have been very easy
for me to follow in the past using my mouse wheel (first added to the mouse
device circa 1995, when a 486/DX33 was still considered a powerful machine).
I'm sorry if I can't find a dumb terminal for a "VAX" with which to read my
email. Perhaps, if i could, I would understand your frustration a little
better.

The only reason I'm making a point of this is that many people come to python
from fields other than computer science or hacker-ology. Posting styles will
vary considerably among these people, so deal with the deviants carefully.
Their differences in styles, like mine, probably arise from the culture of
their respective fields. Most, like me, may not even know what the heck you
are talking about. Also, here is a well written synopsis of the arguments in
favor of top-posting and they may even be strong enough to legitimize the
practice:

http://alpage.ath.cx/toppost/toppost.htm

In light of these arguments, I hereby reserve the right to revert to
top-posting if the compulsion overwhelms me.

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Oct 25 '05 #13

P: n/a
On Tue, 25 Oct 2005 16:20:21 GMT, Ron Adam <rr*@ronadam.com> wrote:
Duncan Booth wrote:
Ron Adam wrote:
James Stroud wrote:

Here it goes with a little less overhead:


<example snipped>
But it's not a dictionary anymore so you can't use it in the same places
you would use a dictionary.

foo(**n)

Would raise an error.

So I couldn't do:

def foo(**kwds):
kwds = namespace(kwds)
kwds.bob = 3
kwds.alice = 5
...
bar(**kwds) #<--- do something with changed items


I agree with Steven D'Aprano's reply, but if you are set on it you could
try this:

>class namespace(dict):


def __init__(self, *args, **kw):
dict.__init__(self, *args, **kw)
self.__dict__ = self
>n = namespace({'bob':1, 'carol':2, 'ted':3, 'alice':4})
>n.bob


1
>n.bob = 3
>n['bob']


3

The big problem of course with this sort of approach is that you cannot
then safely use any of the methods of the underlying dict as they could be
masked by values.

P.S. James, *please* could you avoid top-quoting.


Or worse, the dictionary would become not functional depending on what
methods were masked.
And this approach reverses that, The dict values will be masked by the
methods, so the values can't effect the dictionary methods. But those
specific values are only retrievable with the standard dictionary notation.

class namespace(dict):
__getattr__ = dict.__getitem__
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__

n = namespace()
n.__getattr__ = 'yes' # doesn't mask __getattr__ method.

print n['__getattr__'] -> 'yes'

The value is there and __getattr__() still works. But n.__getattr__
returns the method not the value.

So is there a way to keep the functionality without loosing the methods?
BTW, I agree with Steven concerning data structures. This really isn't
a substitute for a data structure. Many keys will not work with this.

n.my name = 'Ron'
n.(1,2) = 25
n.John's = [ ... ]

The use case I'm thinking of is not as a shortcut for data structures,
but instead, as a way to keep names as names, and maintaining those
names in a group. Thus the namespace association.

def foo(**kwds):
kwds = namespace(kwds)
print kwds.name
print kwds.value
...

name = 'ron'
value = 25
foo( name=name, position=position )

Just had the thought that if you want to add bindings on the fly modifying the
original object, you could use the __call__ method, e.g.,
class NameSpace(dict): ... __getattr__ = dict.__getitem__
... __setattr__ = dict.__setitem__
... __delattr__ = dict.__delitem__
... def __call__(self, **upd):
... self.update(upd)
... return self
... def show(x): print '-- showing %r'%x; return x ... ns = NameSpace(initial=1)
show(ns) -- showing {'initial': 1}
{'initial': 1}

And updating with a second keyword on the fly:
show(show(ns)(second=2))

-- showing {'initial': 1}
-- showing {'second': 2, 'initial': 1}
{'second': 2, 'initial': 1}

FWIW ;-)

Regards,
Bengt Richter
Oct 25 '05 #14

P: n/a
> On Tuesday 25 October 2005 00:31, Duncan Booth wrote:
P.S. James, *please* could you avoid top-quoting James Stroud <js*****@mbi.ucla.edu> writes:
I'm sorry if I can't find a dumb terminal for a "VAX" with which to read my
email. Perhaps, if i could, I would understand your frustration a little
better.


You don't need a VAX. All it takes is trying to dethread a top-posted
conversation. I've given up in frustration on more than one such
venture.
The only reason I'm making a point of this is that many people come to python> from fields other than computer science or hacker-ology. Posting styles will
vary considerably among these people, so deal with the deviants carefully.
I belive Duncan did so. He asked you to "please* avoid to
top-posting".
Their differences in styles, like mine, probably arise from the culture of
their respective fields. Most, like me, may not even know what the heck you
are talking about. Also, here is a well written synopsis of the arguments in
favor of top-posting and they may even be strong enough to legitimize the
practice:
http://alpage.ath.cx/toppost/toppost.htm
Well, if I could find a 300 baud modem, I might understand his
objection to not top-posting (he really only has one). His comments
about why people shouldn't complain about top-posting are full of
suggestions that don't generally work on netnews and mail, though they
may be valid elsewhere, and his suggestion about when to top-post
leaves out the *very important* criteria that you don't expect to read
any replies to your comment, and don't care if you make life difficult
for those who have different expectations.

He's right about inadequately-trimmed repklies, though. Not being on a
300 baud modem, I don't think they're as annoying as top-posting, but
they are certainly something that we can do without.
In light of these arguments, I hereby reserve the right to revert to
top-posting if the compulsion overwhelms me.


That's your right. Be aware that people will ignore, correct and/or
complain about you doing so.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Oct 25 '05 #15

P: n/a


Bengt Richter wrote:
On Tue, 25 Oct 2005 16:20:21 GMT, Ron Adam <rr*@ronadam.com> wrote:

Or worse, the dictionary would become not functional depending on what
methods were masked.
And this approach reverses that, The dict values will be masked by the
methods, so the values can't effect the dictionary methods. But those
specific values are only retrievable with the standard dictionary notation.

class namespace(dict):
__getattr__ = dict.__getitem__
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__

n = namespace()
n.__getattr__ = 'yes' # doesn't mask __getattr__ method.

print n['__getattr__'] -> 'yes'

The value is there and __getattr__() still works. But n.__getattr__
returns the method not the value.

So is there a way to keep the functionality without loosing the methods?
BTW, I agree with Steven concerning data structures. This really isn't
a substitute for a data structure. Many keys will not work with this.

n.my name = 'Ron'
n.(1,2) = 25
n.John's = [ ... ]

The use case I'm thinking of is not as a shortcut for data structures,
but instead, as a way to keep names as names, and maintaining those
names in a group. Thus the namespace association.

def foo(**kwds):
kwds = namespace(kwds)
print kwds.name
print kwds.value
...

name = 'ron'
value = 25
foo( name=name, position=position )


Just had the thought that if you want to add bindings on the fly modifying the
original object, you could use the __call__ method, e.g.,
>>> class NameSpace(dict): ... __getattr__ = dict.__getitem__
... __setattr__ = dict.__setitem__
... __delattr__ = dict.__delitem__
... def __call__(self, **upd):
... self.update(upd)
... return self
... >>> def show(x): print '-- showing %r'%x; return x ... >>> ns = NameSpace(initial=1)
>>> show(ns) -- showing {'initial': 1}
{'initial': 1}

And updating with a second keyword on the fly:
>>> show(show(ns)(second=2))

-- showing {'initial': 1}
-- showing {'second': 2, 'initial': 1}
{'second': 2, 'initial': 1}

FWIW ;-)

Regards,
Bengt Richter


Getting better! ;-)

That (or something similar) might avoid copying the whole thing in some
situations, which is something I am concerned about. But how to change
a dict to a namespace without copying the contents item by item?

I'm not sure where or if this is going anywhere. It may tie back into
the properties groups example (see below) I posted earlier and keep
finding improvements for. ;-)

cheers,
Ron


""" GPobject.py

Grouped Properties Object:

This need has presented itself while programming Tkinter
applications where a *LOT* of keywords are used. I think
property groups would also be good for general interface
building. The external view is of a single cohesive
object, while the internal mechanism keeps the attributes
grouped so they can be forwarded easily as **kwds.

class foo(GPobject):
def __init__(self):
self.properties(name, item_1, item_2, ... item_n)
def getter():
...
def setter():
...
def remover():
...
self.name.doc( __doc__ string )
self.name.get = getter
self.name.set = setter
self.name.remove = remover

* The properties() method can also accept a dictionary.
This will set both the names and the values at the same time.

self.properties(name, dictionary)

class myclass(GPobject):
def __init__(self, **kwds):
self.properties('kwds', **kwds)

* group.setup() allows easy initiation of get, set, remove,
and doc group settings in one step.

self.properties( name, *members )
self.name.setup( get=myget, set='set', del='del',
doc='a property group' )

* Using string flags to indicate default values lets you
shorten the expression further.

self.properties( name, *members )
self.name.setup( myget, 'set', 'del', 'a property group')
The following is only somewhat tested... but it seems to work.
"""

class GPdict(dict):
doc = "a property group"
def doc(self, docstring): self.__doc__ = docstring
def get(self, item): return self[item]
def set(self, item, value): self[item] = value
def remove(self, item): del self[item]
def setup( self, fget='get', fset='set',
fdel='del', doc=doc ):
if fget != 'get': self.get = fget
if fset != 'set': self.set = fset
if fdel != 'del': self.remove = fdel
self.__doc__ = doc

# Some useful common alternate methods to
# replace get, set and remove.
def readonly(self, *args):
raise AttributeError, 'read only property'
def setonce(self, item, value):
if self[item] is None: self[item] = value
else:
raise AttributeError, 'set once property'
def nonremovable(self, *args):
raise AttributeError, 'non removable property'

class GPobject(object):
""" an object that can use grouped properties """
__properties__ = {}
def __new__(cls, *args, **kwds):
cls.__properties__ = {}
return object.__new__(cls, *args, **kwds)
def properties(self, *args, **kwds):
dct = GPdict()
for i in args[1:]:
dct.setdefault(i,None)
dct.update(kwds)
self.__properties__[args[0]] = dct
self.__dict__[args[0]] = dct
def __getattr__(self, name):
for dct in self.__properties__:
if name in self.__properties__[dct]:
return self.__properties__[dct].get(name)
return self.__dict__[name]
def __setattr__(self, name, value):
notprop = True
for dct in self.__properties__:
if name in self.__properties__[dct]:
self.__properties__[dct].set(name,value)
notprop = False
if notprop:
self.__dict__[name] = value
def __delattr__(self, name):
for dct in self.__properties__:
if name in self.__properties__[dct]:
self.__properties__[dct].remove(name)
return
del self.__dict__[name]

=================
### Properties as keyword sorter example,
### (sort to groups, not ordered sort)

class sorter(GPobject):
text_group = str.split('text fill font')
line_group = str.split('line fill arrows')
def __init__( self, text=None, fill=None, line=None,
arrows=None, font=None ):
self.properties('_text', *self.text_group)
self.properties('_line', *self.line_group)
self.text = text
self.fill = fill
self.line = line
self.arrows = arrows
self.font = font

s = sorter(text='hello', fill='black', line='solid', arrows='both')
print 's._text =', s._text
print 's._line =', s._line
print s.__properties__

Oct 25 '05 #16

P: n/a
On Tuesday 25 October 2005 14:27, Mike Meyer wrote:
That's your right. Be aware that people will ignore, correct and/or
complain about you doing so.


If I may be a complete ass: That should be "correct and/or complain about
*your* doing so."

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Oct 25 '05 #17

P: n/a
James Stroud wrote:
On Tuesday 25 October 2005 14:27, Mike Meyer wrote:
That's your right. Be aware that people will ignore, correct and/or
complain about you doing so.

If I may be a complete ass: That should be "correct and/or complain about
*your* doing so."


You *may* be a complete ass. But you don't *appear* to be :-)

now-let's-get-back-to-the-python-ly y'rs - steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Oct 25 '05 #18

P: n/a
On Tue, 25 Oct 2005 17:27:55 -0400, Mike Meyer wrote:
On Tuesday 25 October 2005 00:31, Duncan Booth wrote: Their differences in styles, like mine, probably arise from the culture of
their respective fields. Most, like me, may not even know what the heck you
are talking about. Also, here is a well written synopsis of the arguments in
favor of top-posting and they may even be strong enough to legitimize the
practice:
http://alpage.ath.cx/toppost/toppost.htm


Well, if I could find a 300 baud modem, I might understand his
objection to not top-posting (he really only has one).


Perhaps he is hosting his website on a server with a 300 baud modem? It
times out for me... *wink*

A: Because it messes up the order in which people read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying email habit?
I wouldn't object to top-posting nearly so much if the average top-poster
had the writing skills of an illiterate sloth hunter in the jungles of
Borneo[1], but sadly most of them don't. I get people replying to an email
three weeks after I sent them the original, and they top-post the answer
"Yes, I agree". When I read it, my brain reboots from the sheer inanity of
it. You agree to *what*? Do I really care enough to read through the
entire thread -- which you've so *thoughtfully* quoted in its entirety,
eight levels deep, thank you very much -- to find out what you are
agreeing to?

And then when I do read through it, I discover that what was actually
asked was three or four *specific* questions like "How much memory would
you like your new PC to have?" and "Would you like wireless?".

Top-posting encourages stupid mistakes like that, by encouraging people to
hit send after they've said the first thing they thought of, without
actually reading through the email to see if there are other issues that
need to be dealt with.

[1] There are no sloths in Borneo.

--
Steven.

Oct 25 '05 #19

P: n/a
In my case the deeply nested function calls are recursive calls for a
tree traversal.
This is similar to the visitor design pattern, where the Context class
above is the Visitor. The difference is that the Context instance does
not "visit" or "act" upon the nodes, but just stores state/context
information about the current traversal.

Simon.

Oct 26 '05 #20

P: n/a
James Stroud wrote:
On Tuesday 25 October 2005 00:31, Duncan Booth wrote:
P.S. James, *please* could you avoid top-quoting
Were it not for Steve Holden's providing me with a link off the list,
I would have never known to what it is you are referring. I have read
some relevant literature to find that this is more widely known as
"top-posting". I'll go with majority rules here, but I would like to
say that my lack of "netiquette" in this matter comes from
practicality and not malice.


No, I didn't think it was malice which is why I just added what I
considered to be a polite request at the end of my message. I assumed that
most people either knew the phrase or could find out in a few seconds using
Google so there wasn't much point in rehashing the arguments. Probably I
should have equally lambasted Ron for the heinous crime of bottom-quoting.

In general, there are three ways to quote a message: top-quoting, which
forces people to read the message out of order; bottom-quoting which is
nearly as bad because it hides the new comments; and proper quoting in
context where you trim the message and put specific points under brief bits
of context.

The thread in question had a horrific mix of top and bottom quoting, so
that when I tried to reply at what I thought was an appropriate point in
the thread (<pY*********************@tornado.tampabay.rr.com> ) I think the
order it went was something like:
quote from James (4) comment from Ron (5)
quote from James (2)

comment from Ron (3)
quote from James (2)
quote from Ron (1)


I spent a while trying to trim that down to relevant context, and in
particular trying to work out in what order the original statements had
been made. In the end I gave up and replied to an earlier message which was
more easily trimmable.
Also, here is a well written synopsis of the arguments in
favor of top-posting and they may even be strong enough to legitimize the
practice:


The arguments are mostly sound, but I would draw slightly different
conclusions:

Follow the conventions of the particular newsgroup or mailing list, but
with that in mind, for all replies, Middle Post. Respond to each point in
turn with lots of snipping.

He's right though, its not a religious issue.
Oct 26 '05 #21

P: n/a

Duncan Booth wrote:
James Stroud wrote:
On Tuesday 25 October 2005 00:31, Duncan Booth wrote:
P.S. James, *please* could you avoid top-quoting


Were it not for Steve Holden's providing me with a link off the list,
I would have never known to what it is you are referring. I have read
some relevant literature to find that this is more widely known as
"top-posting". I'll go with majority rules here, but I would like to
say that my lack of "netiquette" in this matter comes from
practicality and not malice.


No, I didn't think it was malice which is why I just added what I
considered to be a polite request at the end of my message. I assumed that
most people either knew the phrase or could find out in a few seconds using
Google so there wasn't much point in rehashing the arguments. Probably I
should have equally lambasted Ron for the heinous crime of bottom-quoting.

In general, there are three ways to quote a message: top-quoting, which
forces people to read the message out of order; bottom-quoting which is
nearly as bad because it hides the new comments; and proper quoting in
context where you trim the message and put specific points under brief bits
of context.


Just to continue this off-topic argument :) -

I've never heard the terms top-quoting, bottom-quoting. I've heard
top-posting and bottom-posting before (lots). But regardless of
however many people use top-quoting and bottom-quoting, surely you're
using them the wrong way around? If I top-post, then that means that
the quote is at the bottom, no?

To quote someone's sig block:
"To top-post is human, to bottom-post and snip is sublime."

Iain

Oct 26 '05 #22

P: n/a


Duncan Booth wrote:
No, I didn't think it was malice which is why I just added what I
considered to be a polite request at the end of my message. I assumed that
most people either knew the phrase or could find out in a few seconds using
Google so there wasn't much point in rehashing the arguments. Probably I
should have equally lambasted Ron for the heinous crime of bottom-quoting.
I usually try to keep things in reasonable context and or order. I tend
to bottom quote only when either the message is short enough to fit on a
single page, or when I'm adding new content that isn't a direct response
to an individual item but builds on the above ideas. Sometimes deciding
what to trim out of various really good replies is difficult. ;-)

In any case, I don't take offense to any suggested improvements. I
wouldn't be surprised if many of my posts were considered hard to follow
at times. A chronic sleeping disorder combined with dyslexia can
sometimes make expressing my thoughts in words rather challenging on
some (most) days.

quote from James (4)


comment from Ron (5)
quote from James (2)

comment from Ron (3)

quote from James (2)

>quote from Ron (1)
I spent a while trying to trim that down to relevant context, and in
particular trying to work out in what order the original statements had
been made. In the end I gave up and replied to an earlier message which was
more easily trimmable.


I was undecided weather to trim the later (earlier) responses or not,
but decided to leave them in.

Also, here is a well written synopsis of the arguments in
favor of top-posting and they may even be strong enough to legitimize the
practice:


The arguments are mostly sound, but I would draw slightly different
conclusions:

Follow the conventions of the particular newsgroup or mailing list, but
with that in mind, for all replies, Middle Post. Respond to each point in
turn with lots of snipping.


In general I find a well written top post in a friarly prompt *email* to
be fine. What I refer to as well written in this case, is where the
author restates the question, points, or issues in their own word first,
and then follow that up with their response and or conclusions.
Especially if it's any sort of official or at least non casual
interchange. In that case the quotes appended to the end serves as
history that can be referenced if needed.

But in news groups, it's best to try and keep things conversational with
as you call middle posts. It allows people to add to the conversation
as if they were all present at the same time, even though they may
actually be replying at varying different times. I tend to try not to
break up paragraphs if possible though, and attempt to break my posts up
into short paragraphs to leave spaces for others to insert their
replies. But I wouldn't claim I'm completely consistent on these issues
myself.

He's right though, its not a religious issue.


Yep, I agree with this also. ;-)

Cheers,
Ron
Oct 26 '05 #23

P: n/a
Ron Adam <rr*@ronadam.com> wrote:
...
class namespace(dict):
def __getattr__(self, name):
return self.__getitem__(name) ... Any thoughts? Any better way to do this?


If any of the keys (which become attributes through this trick) is named
'update', 'keys', 'get' (and so on), you're toast; it really looks like
a nasty, hard-to-find bug just waiting to happen. If you're really
adamant on going this perilous way, you might try overriding
__getattribute__ rather than __getattr__ (the latter is called only when
an attribute is not found "in the normal way").

If you think about it, you're asking for incompatible things: by saying
that a namespace X IS-A dict, you imply that X.update (&c) is a bound
method of X; at the same time, you also want X.update to mean just the
same thing as X['update']. Something's gotta give...!-)
Alex
Oct 26 '05 #24

P: n/a
On 2005-10-26, Duncan Booth <du**********@invalid.invalid> wrote:
James Stroud wrote:
On Tuesday 25 October 2005 00:31, Duncan Booth wrote:
P.S. James, *please* could you avoid top-quoting


Were it not for Steve Holden's providing me with a link off the list,
I would have never known to what it is you are referring. I have read
some relevant literature to find that this is more widely known as
"top-posting". I'll go with majority rules here, but I would like to
say that my lack of "netiquette" in this matter comes from
practicality and not malice.


No, I didn't think it was malice which is why I just added what I
considered to be a polite request at the end of my message. I assumed that
most people either knew the phrase or could find out in a few seconds using
Google so there wasn't much point in rehashing the arguments. Probably I
should have equally lambasted Ron for the heinous crime of bottom-quoting.

In general, there are three ways to quote a message: top-quoting, which
forces people to read the message out of order;


Uh, no. Isn't what we're doing here top-quoting? The quoted
stuff is at the top. Everything is in chronological order. I
think what you're referring to is "top-posting".

--
Grant Edwards grante Yow! ... If I had heart
at failure right now,
visi.com I couldn't be a more
fortunate man!!
Oct 26 '05 #25

P: n/a
Grant Edwards wrote:
Uh, no. Isn't what we're doing here top-quoting? The quoted
stuff is at the top. Everything is in chronological order. I
think what you're referring to is "top-posting".


Yes, Iain King already pointed this out.
Oct 26 '05 #26

P: n/a
On 2005-10-26, Duncan Booth <du**********@invalid.invalid> wrote:
Grant Edwards wrote:
Uh, no. Isn't what we're doing here top-quoting? The quoted
stuff is at the top. Everything is in chronological order. I
think what you're referring to is "top-posting".


Yes, Iain King already pointed this out.


Sorry for being rudundent -- I've only been sporadically
reading this thread.

--
Grant Edwards grante Yow! I'm sitting on my
at SPEED QUEEN... To me,
visi.com it's ENJOYABLE... I'm
WARM... I'm VIBRATORY...
Oct 26 '05 #27

P: n/a


Alex Martelli wrote:
Ron Adam <rr*@ronadam.com> wrote:
...
class namespace(dict):
def __getattr__(self, name):
return self.__getitem__(name)
...
Any thoughts? Any better way to do this?

If any of the keys (which become attributes through this trick) is named
'update', 'keys', 'get' (and so on), you're toast; it really looks like
a nasty, hard-to-find bug just waiting to happen. If you're really
adamant on going this perilous way, you might try overriding
__getattribute__ rather than __getattr__ (the latter is called only when
an attribute is not found "in the normal way").


Thanks Alex, I was wondering what the difference between __getattr__ and
__getattribute__ was.

If you think about it, you're asking for incompatible things: by saying
that a namespace X IS-A dict, you imply that X.update (&c) is a bound
method of X; at the same time, you also want X.update to mean just the
same thing as X['update']. Something's gotta give...!-)

Alex


Part of the motivation of this is to try and keep names as names and
data as data in my programs. I would use dictionaries for data storage,
and namespace_dicts for strictly name/value passing. So some
limitations with names are expected just as they would exist anywhere
else with object names. Ie.. can't use keywords, and using names of
methods can cause objects to break, etc...

This seems to be the closest to a generic namespace object so far.

class namespace(dict):
__getattribute__ = dict.__getitem__
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__

Not having any public and/or visible methods of it's own is a good thing
here. So you would need to use dict.update(A_namespace, A_dict) in this
case. I don't think thats a problem. Maybe a namespace object, (as I
am thinking of it), should not have it's own interface, but inherit one
from the object it's inserted into?

Anyway... this is experimental, and not production code of any sort. ;-)

Cheers,
Ron

Oct 26 '05 #28

This discussion thread is closed

Replies have been disabled for this discussion.