P
Peter Otten
There is currently a discussion on python-dev about an extract() function
which offers fast access to list items and object attributes. It could
serve, e. g., as the key argument of the future list.sort() method:
extract("attr") # extract an attribute
extract(1) # extract a list item
Below is a slight variation of this idea, together with a pure-python
implementation. As a "real" C version is currently beyond me, I chose not
to post it on python-dev.
Following variants are possible:
# extract an attribute
extract.attr
extract(name="attr") # necessary when attribute name only known at runtime
# extract a list item or slice
extract[1]
extract[:]
extract(index=1) # for symmetry only
# extract a dictionary value
extract["key"]
extract(key="key") # for symmetry only
<toy implementation>
# the gory details
class GetItem(object):
def __init__(self, index):
self.index = index
def __call__(self, item):
return item[self.index]
class GetAttr(object):
def __init__(self, name):
self.name = name
def __call__(self, obj):
return getattr(obj, self.name)
class Extract(object):
def __getitem__(self, key):
return GetItem(key)
def __getattribute__(self, name):
return GetAttr(name)
def __call__(self, name=None, key=None, index=None):
assert sum([name is None, key is None, index is None]) == 2, (
"Please provide only one of these arguments: name, key, index")
if name is not None: return GetAttr(name)
if key is not None: return GetItem(key)
return GetItem(index)
extract = Extract()
# usage demonstration
class Demo:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return "(x=%s, y=%s)" % (self.x, self.y)
__repr__ = __str__
indexSample = [(1, 10), (2, 20), (3, 30)]
keySample = [{"x": x, "y": y} for x, y in indexSample]
attrSample = [Demo(*xy) for xy in indexSample]
print "Index", indexSample
print "Key", keySample
print "Attribute", attrSample
def printSeq(seq, extractor):
for item in seq:
print extractor(item),
print
printSeq(indexSample, extract[0])
printSeq(indexSample, extract(index=1))
printSeq(indexSample, extract[:])
printSeq(attrSample, extract.x)
printSeq(attrSample, extract(name="y"))
printSeq(keySample, extract["x"])
printSeq(keySample, extract(key="y"))
</toy implementation>
Comments welcome
Peter
which offers fast access to list items and object attributes. It could
serve, e. g., as the key argument of the future list.sort() method:
extract("attr") # extract an attribute
extract(1) # extract a list item
Below is a slight variation of this idea, together with a pure-python
implementation. As a "real" C version is currently beyond me, I chose not
to post it on python-dev.
Following variants are possible:
# extract an attribute
extract.attr
extract(name="attr") # necessary when attribute name only known at runtime
# extract a list item or slice
extract[1]
extract[:]
extract(index=1) # for symmetry only
# extract a dictionary value
extract["key"]
extract(key="key") # for symmetry only
<toy implementation>
# the gory details
class GetItem(object):
def __init__(self, index):
self.index = index
def __call__(self, item):
return item[self.index]
class GetAttr(object):
def __init__(self, name):
self.name = name
def __call__(self, obj):
return getattr(obj, self.name)
class Extract(object):
def __getitem__(self, key):
return GetItem(key)
def __getattribute__(self, name):
return GetAttr(name)
def __call__(self, name=None, key=None, index=None):
assert sum([name is None, key is None, index is None]) == 2, (
"Please provide only one of these arguments: name, key, index")
if name is not None: return GetAttr(name)
if key is not None: return GetItem(key)
return GetItem(index)
extract = Extract()
# usage demonstration
class Demo:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return "(x=%s, y=%s)" % (self.x, self.y)
__repr__ = __str__
indexSample = [(1, 10), (2, 20), (3, 30)]
keySample = [{"x": x, "y": y} for x, y in indexSample]
attrSample = [Demo(*xy) for xy in indexSample]
print "Index", indexSample
print "Key", keySample
print "Attribute", attrSample
def printSeq(seq, extractor):
for item in seq:
print extractor(item),
printSeq(indexSample, extract[0])
printSeq(indexSample, extract(index=1))
printSeq(indexSample, extract[:])
printSeq(attrSample, extract.x)
printSeq(attrSample, extract(name="y"))
printSeq(keySample, extract["x"])
printSeq(keySample, extract(key="y"))
</toy implementation>
Comments welcome
Peter