473,396 Members | 2,140 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

generic object implementation

So I'm trying to get a prototype implementation of the 'generic object'
type. (I'm currently calling it 'bunch', but only because I can't
really think of anything better.) I'd like some feedback on what
methods it needs to support. Ideally I'd keep this as minimal as
possible...

Remember that the goal of the 'generic object' type is to allow the
programmer to make the design decision that attribute-style access is
more appropriate than []-style access. Given that, my feeling is that
the 'generic object' type should *not* support __(get|set|del)item__ ,
though I'm still undecided on __len__, __iter__, __contains__, items,
keys, values, etc.

Here's what I have currently:

import operator as _operator

class bunch(object):
def __init__(self, **kwds):
self.__dict__.update(kwds)

def __eq__(self, other):
if not isinstance(other, bunch):
return False
attrs = set(self.__dict__)
if attrs != set(other.__dict__):
return False
for attr in attrs:
if not getattr(self, attr) == getattr(other, attr):
return False
return True

def __repr__(self):
return '%s(%s)' % (self.__class__.__name__,
', '.join('%s=%r' % (k, v)
for k, v in self.__dict__.items()))

def update(self, other):
self.__dict__.update(other.__dict__)

@classmethod
def frommapping(cls, mapping,
getkeys=iter, getitem=_operator.getitem):
result = bunch()
for key in getkeys(mapping):
value = getitem(mapping, key)
try:
value = bunch.frommapping(value)
except TypeError:
pass
setattr(result, key, value)
return result
Jul 18 '05 #1
3 2000
On Sun, 21 Nov 2004 23:55:48 GMT, Steven Bethard <st************@gmail.com> wrote:
So I'm trying to get a prototype implementation of the 'generic object'
type. (I'm currently calling it 'bunch', but only because I can't
really think of anything better.) I'd like some feedback on what
methods it needs to support. Ideally I'd keep this as minimal as
possible... UIAM 'bunch' already has a related meaning from c.l.py past (approx the first
three lines of your class), so how about 'gob' ? ;-)

Remember that the goal of the 'generic object' type is to allow the
programmer to make the design decision that attribute-style access is
more appropriate than []-style access. Given that, my feeling is that
the 'generic object' type should *not* support __(get|set|del)item__ ,
though I'm still undecided on __len__, __iter__, __contains__, items,
keys, values, etc.

Here's what I have currently:

import operator as _operator

class bunch(object):
def __init__(self, **kwds):
self.__dict__.update(kwds)

def __eq__(self, other):
if not isinstance(other, bunch):
return False
attrs = set(self.__dict__)
if attrs != set(other.__dict__):
return False
for attr in attrs:
if not getattr(self, attr) == getattr(other, attr):
return False
return True

def __repr__(self):
return '%s(%s)' % (self.__class__.__name__,
', '.join('%s=%r' % (k, v)
for k, v in self.__dict__.items()))

def update(self, other):
self.__dict__.update(other.__dict__)

@classmethod
def frommapping(cls, mapping,
getkeys=iter, getitem=_operator.getitem):
result = bunch()
for key in getkeys(mapping):
value = getitem(mapping, key)
try:
value = bunch.frommapping(value)
except TypeError:
pass
setattr(result, key, value)
return result


I dunno, begins to look more like a dict with getattr access substituted for __getitem__
than a primitive generic object...
class dbunch(dict): ... def __metaclass__(name, bases, cdict):
... cdict.update(dict.__dict__)
... cdict['__getattr__'] = cdict['__getitem__']
... cdict['__setattr__'] = cdict['__setitem__']
... cdict['__delattr__'] = cdict['__delitem__']
... def raiseunsub(*ignore): raise TypeError, 'unsubscriptable object'
... cdict['__getitem__'] = raiseunsub
... cdict['__setitem__'] = raiseunsub
... cdict['__delitem__'] = raiseunsub
... return type(name, bases, cdict)
... db = dbunch(x=123)
db {'x': 123} db.x 123 db['x'] Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in raiseunsub
TypeError: unsubscriptable object db.y = 456
db {'y': 456, 'x': 123} db.x = 789
db {'y': 456, 'x': 789} del db.x
db {'y': 456} db.x = 101112
db.z = 131415
db {'y': 456, 'x': 101112, 'z': 131415} db.keys() ['y', 'x', 'z'] db.values() [456, 101112, 131415] db.items() [('y', 456), ('x', 101112), ('z', 131415)] for k in db: print k,

...
y x z

.... and etc. methods from dict, so should it be a restricted builtin subclass of dict
or derive from object directly? It the hope for a lean representation for small numbers
of items?

Regards,
Bengt Richter
Jul 18 '05 #2
Bengt Richter wrote:

UIAM 'bunch' already has a related meaning from c.l.py past (approx the first
three lines of your class), so how about 'gob' ? ;-)
Yeah, the intent is basically to provide that 3-liner. Could be that's
all that should be in the class... It wouldn't cover all my use cases,
but I'd certainly be happier with that than nothing.
I dunno, begins to look more like a dict with getattr access substituted for __getitem__
than a primitive generic object...
Yeah, the idea is to provide getattr access instead of __getitem__ --
that's basically what the original 3-liner does too. For my uses, I
don't think I'd ever want any of __len__, __iter__, __contains__, items,
keys, values, etc. but I wasn't the only one who seemed interested in
the idea... The pyparsing code in particular might benefit from
something like the frommapping method (and I know I could use it to
convert XML DOM into nested objects)...
>>> class dbunch(dict):

... def __metaclass__(name, bases, cdict):
... cdict.update(dict.__dict__)
... cdict['__getattr__'] = cdict['__getitem__']
... cdict['__setattr__'] = cdict['__setitem__']
... cdict['__delattr__'] = cdict['__delitem__']
... def raiseunsub(*ignore): raise TypeError, 'unsubscriptable object'
... cdict['__getitem__'] = raiseunsub
... cdict['__setitem__'] = raiseunsub
... cdict['__delitem__'] = raiseunsub
... return type(name, bases, cdict)
...


Interesting approach here. I hadn't thought of going this way. While I
hadn't planned on supporting the whole mapping interface, this would
certainly be an easy way to do so. I'll probably wait for a little more
feedback to see what the others who were interested want to use these
for... If people have good use cases for keys, items, etc. this is
probably the right answer...
It the hope for a lean representation for small numbers
of items?


Not exactly sure what you mean by lean...

All the use cases I have for it only care about 'obj.x' type access, and
don't really use any of the other container type methods. So in my
case, __init__, __eq__, __repr__, update and frommapping do pretty much
everything I want... If this is true for everyone else's use cases, I'd
rather not "pollute" the class with a bunch of dict methods... But I'm
certainly willing to be persuaded that other methods are also essential.

Steve
Jul 18 '05 #3
Steven Bethard wrote:
So I'm trying to get a prototype implementation of the 'generic object'
type. (I'm currently calling it 'bunch', but only because I can't
really think of anything better.) I'd like some feedback on what
Me neither. I called my bunch equivalent Struct, but that name seems
ambiguous because of the struct module.
methods it needs to support. Ideally I'd keep this as minimal as
possible...

Remember that the goal of the 'generic object' type is to allow the
programmer to make the design decision that attribute-style access is
more appropriate than []-style access. Given that, my feeling is that
the 'generic object' type should *not* support __(get|set|del)item__ ,
though I'm still undecided on __len__, __iter__, __contains__, items,
keys, values, etc.
Please, no. (except __iter__(), maybe)

Here's what I have currently:

import operator as _operator

class bunch(object):
def __init__(self, **kwds):
self.__dict__.update(kwds)

def __eq__(self, other):
Maybe just
return (type(self) == type(other)
and self.__dict__ == other.__dict__)

as you won't get properties right anyway.
Not sure whether that should be enforced, but subclassing bunch doesn't seem
a good idea to me.
if not isinstance(other, bunch):
return False
attrs = set(self.__dict__)
if attrs != set(other.__dict__):
return False
for attr in attrs:
if not getattr(self, attr) == getattr(other, attr):
return False
return True

def __repr__(self):
return '%s(%s)' % (self.__class__.__name__,
', '.join('%s=%r' % (k, v)
for k, v in self.__dict__.items()))

def update(self, other):
self.__dict__.update(other.__dict__)
I don't think update() is necessary, but if so, I'd rather have (untested)

def update(self, *other, **kw):
if other:
if len(other) != 1:
raise TypeError
other = other[0]
if isinstance(other, bunch):
other = other.__dict__
self.__dict__.update(other)
self.__dict__.update(kw)

i. e. something matching 2.4's dict.update() functionality as closely as
possible (and appropriate).

@classmethod
def frommapping(cls, mapping,
getkeys=iter, getitem=_operator.getitem):
result = bunch()
Substitute bunch with cls throughout.
Should there also be a getpairs argument that would yield (key, value)
pairs?
for key in getkeys(mapping):
value = getitem(mapping, key)
try:
value = bunch.frommapping(value)
except TypeError:
pass
setattr(result, key, value)
return result


Seeing how many aspects are to consider with such a simple thing as a bunch,
it would really be a benefit if one standard approach were available to
substitute all the ad hoc solutions currently out there in the wild.
Good luck with your effort.

Peter

Jul 18 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

49
by: Steven Bethard | last post by:
I promised I'd put together a PEP for a 'generic object' data type for Python 2.5 that allows one to replace __getitem__ style access with dotted-attribute style access (without declaring another...
3
by: SimonH | last post by:
Hi all, I would like to make a generic set of methods that could be called regardless of the database behind the scenes. One of the methods I would like would take a string sql statement and...
3
by: SimonH | last post by:
Hi all, I would like to make a generic set of methods that could be called regardless of the database behind the scenes. One of the methods I would like would take a string sql statement and...
13
by: rkausch | last post by:
Hello everyone, I'm writing because I'm frustrated with the implementation of C#'s generics, and need a workaround. I come from a Java background, and am currently writing a portion of an...
7
by: Dave | last post by:
I've got these declarations: public delegate void FormDisplayResultsDelegate<Type>(Type displayResultsValue); public FormDisplayResultsDelegate<stringdisplayMsgDelegate; instantiation:...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.