python - Subclassing datatypes that have views in Python2.7 and Python3 -


python 3 introduced views (see this question). backported python 2.7. in process of subclassing dict in python 2.7 application (though goal port python 3 well). wondering if - , how - subclass .viewitems() , similar functions in such way behave original views.

here intent: have dictonary this:

data = my_subclassed_dict data["_internal"] = "internal_value" data["key"] = "value" list(data.keys()) == ["key"] 

that is, filter stat starts "_". works fine far: iterators yield , lists use list comprehension filters undesired values. however, items have no connection dict anymore (which fine, feels dict). however, both ways, not work:

keys = data.viewkeys() "key" in keys del data["key"] "key" not in keys # false ! 

the last part not work because there no reference original keys, python won't notice.

so: there simple way achieve (without re-implementing of logic!)?

this more of question out of interest don't see apply in scenario.

the view objects 'empty' proxies. point original dictionary.

unfortunately, current dictionary view objects not reusable. quoting source code:

/* todo(guido): views objects not complete:   * support more set operations  * support arbitrary mappings?    - either these should static or exported in dictobject.h    - if public should in builtins */ 

note support arbitrary mappings entry; these objects not support arbitrary mappings, nor can create new instances or subclass these python code:

>>> type({}.viewkeys())({}) traceback (most recent call last):   file "<stdin>", line 1, in <module> typeerror: cannot create 'dict_keys' instances >>> class myview(type({}.viewkeys())): pass ...  traceback (most recent call last):   file "<stdin>", line 1, in <module> typeerror: error when calling metaclass bases     type 'dict_keys' not acceptable base type 

you forced create own , implement hooks view objects support:

class dictkeys(object):     def __init__(self, parent):         self.parent = parent      def __len__(self):         return len(self.parent)      def __contains__(self, key):         return key in self.parent      def __iter__(self):         return iter(self.parent) 

etc.

the methods original objects implement are:

>>> dir({}.viewkeys()) ['__and__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__'] 

the __and__, __or__, __sub__, __xor__, __rand__, __ror__, __rsub__ , __rxor__ methods implement overrides &, | , ^ operators provide set operations.

if reasonably secure in reading c code, take @ view objects implementation peek @ how implement methods.


Comments