Reputation: 7671
Is it possible to assign attributes to the 'Nonetype' object
to tell Python what to do if they are called?
Here is my problem:
I have a class that functions as a library to store instances of myOtherObject
. Before adding an instance, it first checks if that key already exists and then appends the data to the instance assigned to that key rather than overwriting it.
class MyClass:
def __init__(self):
self.myLibrary = {}
def __setitem__(self, key, item):
if key not in self.myLibrary:
self.myLibrary[key] = myOtherObject(name=item[0], attr1=[item[1]], attr2=[item[2]])
else:
self.myLibrary[key].attr1.append(item[1])
self.myLibrary[key].attr2.append(item[2])
def __getitem__(self, key):
if key in self.myLibrary:
return self.myLibrary[key]
else:
return None #???
When retrieving data from the library it should check if the key exists too, and only return the assigned object if the key exists. This works fine or calling just the object, however not when calling the attributes of that object:
>>> o = MyClass()
>>> o['key1'] = ['name1','b','c']
>>> o['key1']
<__main__.myOtherObject instance at 0x05509B48>
>>> o['key1'].attr1
'b'
>>> o['key2']
>>> o['key2'].attr1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'attr1'
Can I somehow tell Python not to do anything and just return None
when attributes attr1
and attr2
are called from the 'NoneType' object
?
Upvotes: 0
Views: 2434
Reputation: 43054
That's probably the wrong question to ask. The proper (pythonic) thing to do there in the __getitem__
method is to raise KeyError
exception. Then you handle that exception in the caller, or higher up in an appropriate place that can deal with it.
Upvotes: 0
Reputation: 49866
Is it possible to assign attributes to the 'Nonetype' object
No.
>>> o = None
>>> o.foo = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'foo'
>>> setattr(o,'foo',1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'foo'
>>> getattr(o,'foo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'foo'
Before adding an instance, it first checks if that key already exists and then appends the data to the instance assigned to that key rather than overwriting it.
This is a classic use case for a defaultdict:
import collections
d = collections.defaultdict(list)
d['foo'].append(1)
print d #=> defaultdict(<type 'list'>, {'foo': [1]})
When retrieving data from the library it should check if the key exists too, and only return the assigned object if the key exists. This works fine or calling just the object, however not when calling the attributes of that object:
OK. What do you want to happen when the key does not exist?
Can I somehow tell Python not to do anything and just return None when attributes attr1 and attr2 are called from the 'NoneType' object?
What does this mean? If you attempt to access an attribute which does not exist, you get an exception, as above. The solution would be to handle the exception, and return None
; but it would be much better to let the exception propagate, because None
is not a valid input.
In summary, everything you want can be achieved with a defaultdict. Probably don't create your own class.
Upvotes: 1
Reputation: 55263
Use getattr
:
>>> o = None
>>> print getattr(o, "attr1", None)
None
Upvotes: 0