When we say 'One obvious way...', do we mean 'generally obvious' or does that matter?
yaipa
yaipa at aol.com
Wed Sep 18 17:59:24 EDT 2002
Code from mail thread:
http://groups.google.com/groups?dq=&hl=en&lr=&ie=UTF-8&frame=right&th=ef69520e5c
dd3170&seekm=mailman.1031971577.27090.python-list%40python.org#link1
I LIKE the below code snippet. While it might be Pythonic, it will
only be 'obvious' to a Python programmer with some experience under
his/her belt.
*** Comments begin again after code snippet ****
-------------------------------------------------------------------------
#!/usr/bin/env python
import inspect
def make_undefined(cls, attr):
def undefined(self, *args, **kwargs):
msg = "'%s' object has no attribute '%s'" % (cls.__name__, attr)
raise AttributeError(msg)
return undefined
def is_magic(attr):
prefix = suffix = '__'
return attr.startswith(prefix) and attr.endswith(suffix)
class Restricted(type):
common = ['__class__', '__defined__', '__dict__', '__doc__',
'__getattribute__', '__init__', '__new__']
def __new__(cls, classname, bases, classdict):
defined_key = 'defined'
defined = classdict.get(defined_key, []) + Restricted.common
# If a non-magic attribute from any base class is not in common or
# defined, hide it with a method that raises a descriptive
# AttributeError (mimicking Python).
for base in bases:
for k, v in inspect.getmembers(base):
if not is_magic(k) and k not in defined:
classdict[k] = make_undefined(cls, k)
return type.__new__(cls, classname, bases, classdict)
class RestrictedDict(dict):
__metaclass__ = Restricted
defined = ['put', 'get', 'keys', 'items', 'values']
f = RestrictedDict()
print f.keys
print f.keys()
f['a'] = 'b'
print f.keys()
try:
f.clear()
except AttributeError:
pass
print f.keys()
-------------------------------------------------------------------------
*** More Comments ***
-------------------------------------------------------------------------
The flip side of this would be to build up accessors with a root
class that can only 'get' a key or keys and finish with a child
class that can get/set/add and destroy key(s) in the dictionary. Then
the user of such a library can inherit from the accessor class that which
fits his/her needs. While this is practiced in other languages, I
don't see it much used in Python. Does the 'one obverse' rule mean the
one way that is more 'Generic' or more 'Pythonic'?
As a note, here are my accessors and a couple of data dictionary
classes
-------------------------------------------------------------------------
class StaticFinalDictionaryMethods:
#1. class only allows the getting of dictionary names/values.
# Private Class level Vars.
def __init__ (self):
pass
def getKeys(self):
return self._dictionary.keys()
def getNamePairs(self):
return self._dictionary.items()
def getByKey(self, _key, _index = 'None'):
# test to make sure key is valid
if self._dictionary.has_key(_key):
if _index == 'None' or (_index >= self.min and _index < \
len(self._dictionary[_key])):
if _index == 'None':
return self._dictionary[_key]
else:
return self._dictionary[_key][_index]
else:
return 'None'
else:
return 'no_such_key'
class BasicDictionaryMethods(StaticFinalDictionaryMethods):
#1. class allows the getting of dictionary names/values.
#2. class allows the setting of dictionary values by hash name.
# Private Class level Vars.
def __init__(self):
# Python requires us to explicity call the super class
StaticFinalDictionaryMethods.__init__(self)
#Class private Setter for Task startup initilization
# Does not support updating single element of a tuple.
def setByKey(self, _key, _value, _index = 'None'):
# test to make sure key is valid
if self._dictionary.has_key(_key):
if _index == 'None':
# set tuple here
self._dictionary[_key] = _value
else:
print _key, " - ERROR, TaskCore.setByKey().error - no_such_key"
class DynamicDictionary(BasicDictionaryMethods):
def __init__(self):
BasicDictionaryMethods.__init__(self)
def addkey(self, _key, _value):
self._dictionary.setdefault(_key,[]).append(_value)
# end accessors
#---------------------------------------------------------------
#
class ExitTerms(TaskDataAccess.StaticFinalDictionaryMethods):
# Private Class level Vars.
def __init__ (self):
# explicit call to the super class
TaskDataAccess.StaticFinalDictionaryMethods.__init__ (self)
# private dictionary, only 'self.' class methods can access.
self._dictionary = {
'ttf' : None,
'exitKey' : "unset_exitKey",
'symptom' : "unset_symptom",
'message' : "unset_message",
}
class DynamicKeys(TaskDataAccess.DynamicDictionary):
# Private Class level Vars.
def __init__ (self):
# explicit call to the super class
TaskDataAccess.DynamicDictionary.__init__ (self)
self.min = 0
# Build DataStructure and __init__ each '_key' in dictionary.
# -------------------------------------------------------------
# private dictionary, only 'self.' class methods can access.
self._dictionary = {}
More information about the Python-list
mailing list