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