I'm creating a customized class that inherits dict
with __init__
, __setitem__
, __delitem__
, and update
as functions of this custom class. When creating an instance of the the class in a jupyter notebook, I would like to tab-complete when dot accessing attributes of this instance:
some_instance = Foo()
some_instance. # pressing tab should only show 'update'
and dir()
would print
dir(some_instance)
# output: ['update']
The official docs weren't too helpful beyond explaining simply what __dir__
does, and ipython tab completion for custom dict class didn't help me with this too much.
I'm not really sure how this works or what it's doing, but adding following function to the class does exactly what I want:
def __dir__(self):
return ['update']
Here's what I have so far:
# this file is located in some_lib
import json
def save(obj, name):
with open(name, 'w+') as file_:
json.dump(obj, file_)
def load(name):
with open(name, 'r') as file_:
return json.load(file_)
class BijectiveDict(dict):
"""
References
https://stackoverflow.com/questions/1456373/two-way-reverse-map
"""
def __init__(self, dict_={}):
assert isinstance(dict_, dict), "Argument Error: dict_ is not of type dict"
for key, val in dict_.items():
self.update(key, val)
def __setitem__(self, x, y):
# override how self[key] = value works since this class inherits Dict.
# this way, self.add can work as expected
# delete any old pairs that contain x or y
if x in self:
del self[x]
if y in self:
del self[y]
dict.__setitem__(self, x, y)
dict.__setitem__(self, y, x)
def __delitem__(self, key):
dict.__delitem__(self, self[key])
dict.__delitem__(self, key)
def __len__(self):
# returns number of unique mappings
return dict.__len__(self) // 2
def __dir__(self):
return ["update"]
def update(self, x, y):
self[x] = y
If I have
import some_lib
some_map = some_lib.BijectiveDict()
some_map. # using dot access and pressing tab returns methods from the dict class
then dot accessing has the following tab-completions (if __dir__
is not defined):
['clear',
'copy',
'fromkeys',
'get',
'items',
'keys',
'pop',
'popitem',
'setdefault',
'test_name',
'update',
'values']
Is defining __dir__
as such the only way? If my class will have a bunch of methods and I forget to include that in the list returned by dir, what do I do then? Is there an automatic way?
On a similar note, why does tab-completing some_lib shows json, save, load
?
Do I also have to define another __dir__
?