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:


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()
except AttributeError:
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  
class StaticFinalDictionaryMethods:
   #1. class only allows the getting of dictionary names/values.

   # Private Class level Vars.
   def __init__ (self):

   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 < \
            if _index == 'None':
               return self._dictionary[_key]
               return self._dictionary[_key][_index]
            return 'None'
         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

   #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
         print _key, " - ERROR, TaskCore.setByKey().error - no_such_key"

class DynamicDictionary(BasicDictionaryMethods):
   def __init__(self):

   def addkey(self, _key, _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