Reputation: 18205
I know this question sounds very basic. But I can't find it using Google. I know that there are dictionaries that look like
o = {
'a': 'b'
}
and they're accessed with o['a']
. But what are the ones that are accessed as o.a
called? I know they exist because I'm using optparse library and it returns an object accessible like that.
Upvotes: 2
Views: 158
Reputation: 69190
__getattr__
is the method you want to implement, along with __setattr__
. Here is a very simplistic example (no error checking, etc) that shows an object which allows both dictionary-style and attribute-style access:
Missing = object()
class AttrElem(object):
def __init__(self, **kwds):
self.items = kwds.copy()
def __getitem__(self, name):
result = self.items.get(name, Missing)
if result is not Missing:
return result
raise KeyError("key %r not found" % name)
def __setitem__(self, name, value):
self.items[name] = value
def __getattr__(self, name):
result = self.items.get(name, Missing)
if result is not Missing:
return result
raise AttributeError("attribute %r not found" % name)
def __setattr__(self, name, value):
if name == 'items':
object.__setattr__(self, name, value)
else:
self.items[name] = value
def __repr__(self):
return 'AttrElem(%s)' % ', '.join(
["%s:%s" % (k, v) for k, v in self.items.items()]
)
In use it looks like this:
example = AttrElem(this=7, that=9)
print(example)
example.those = 'these'
example['who'] = 'Guido'
print(example)
As you can see from the code __getitem__
and __getattr__
are both very similary, differing only in the exception that gets raised when the target cannot be found.
Upvotes: 0
Reputation: 2635
You can access the variables as a dictionary in "new style classes". I think you have to be a little careful though.
>>> class C(object): # python 2 code, inheriting from 'object' is automatic in 3
a = 5
def __init__(self):
self.j = 90
>>> c = C()
>>> c.__dict__
{'j': 90}
>>> print c.j
90
>>> print c.a
5
notice that 'j' showed up in the dictionary and 'a' didn't. It looks to have something to do with how they are initialized. I'm a little confused by that behavior and wouldn't mind an explanation from a guru :D
Edit:
Doing a little more playing, it is apparent why they decided to go with the behavior above (but it is still a little strange
>>> class C(object):
a = 5
def __init__(self):
self.j = 90
self.funct = range # assigning a variable to a function
>>> c = C()
>>> c.__dict__
{'j': 90, 'funct': <built-in function range>}
I think it separates the class object (which would be the same for every class) with new class members (such as those initiated inside init). If I now do
>>> c.newvar = 234
>>> c.__dict__
{'j': 90, 'newvar': 234, 'funct': <built-in function range>}
You can see it is building a dictionary! Hopefully this helps :D
Upvotes: 1
Reputation: 61449
Looks to me like optparse
simulates an attribute interface to a hidden dict
, but there's a standard library that does something sort of similar, if not really a dictionary: collections.namedtuple
. I can't speak to the other mechanisms presented here.
Upvotes: 1
Reputation:
You can not access dicts using the '.' unless you implement your own dict type by deriving from dict and providing access through the '.' notation by implementing the __getattribute__()
API which is in charge for performing attribute style access.
See http://docs.python.org/reference/datamodel.html#object.__getattribute__
Upvotes: 2
Reputation: 273686
name.attribute
is object access in Python, not dict access
Upvotes: 0