Add kwargs to built-in function object
![](https://secure.gravatar.com/avatar/bf0ee222dbef43f7743772df65fa8ac8.jpg?s=120&d=mm&r=g)
I would like to propose to change the built-in function "object" to have the following syntax: object(**kwargs) Return a new featureless object. object is a base for all new style classes. It has the methods that are common to all instances of new style classes. If kwargs is given, the returned object's __dict__ will be kwargs (or something to that effect). An example: a = object(one=1, two=2) a.one # returns 1 a.two # returns 2 The justification: On several occasions I have needed a collection of attributes to represent a single item. When this happens, there are really three options: 1. Use a tuple. This works well for temporarily re-packaging items in a loop or for quick-and-dirty code, but it rapidly becomes unreadable and hard to maintain. It is not long before you forget what order the attributes are in, and at first glance, it is not clear what kind of object is being indexed. 2. Use a dict. This is an improvement over tuples on readability, but they can be a pain to build and overly-cumbersome to access later. I understand that dicts are used all over the place in Python, but I still think of them (in the general case) as a map of keys to values where the dict represents a collection, not an object. 3. Use a class. This requires coming up with a name for the class and then writing the class (admittedly, this should be easy). Afterwards, this is the most convenient, readable method for representing the data, but since it requires non-trivial effort up front, this method may be avoided until it's truly apparent that it is necessary. A real-world example: Let's say that I want to have a map of employee SSNs to employee data. I am going to be manipulating this information in various ways, but not really in any ways that justify the use of class methods. At any rate, let's build this data from a file where each line is SSN First Last Salary with the items being whitespace-delimited. The code, then, will be: employees = {} for ssn, first, last, salary in (line.split() for line in open(employee_file)): employees[ssn] = (ssn, first, last, salary) # tuple method employees[ssn] = {"ssn": ssn, "first": first, "last": last, "salary": salary} # dict method employees[ssn] = Employee(ssn, first, last, salary) # assumes class with proper constructor # first name of employee with SSN employees[SSN][1] # tuple method -- quite unreadable employees[SSN]["first"] # dict method -- more readable but sub-optimal employees[SSN].first # class method -- readable and simple Now, because of the advantages the class method offers in terms of readability, I have written a convenience class that makes using it easier: class Record: """ A class intended to provide a simple interface for creating objects with named fields. That is, instead of returning a tuple and indexing it or writing a unique class, you can simply do something like: a = Record(x=1, y=2) a.x # 1 a.y # 2 a # Record(x=1, y=2) """ def __init__ (self, **kwargs): self.__dict__.update(kwargs) def __repr__ (self): return "Record(%s)" \ % ", ".join("%s=%s" \ % field for field in self.__dict__.iteritems()) Now, the line in the for loop above becomes employees[ssn] = Record(ssn=ssn, first=first, last=last, salary=salary) and I have completely avoided the need to define a unique class. Note that as the number of fields increases, this becomes easier to use inline than the dict method, at the same time that it avoids the upfront costs of having to build a new class for every distinct type of object in the program. It turns out that other people find such a method useful as well. According to Catherine Devlin on the centralOH Python list, it is recipe 4.18 from the Python Cookbook (2nd ed.). Several others from the mailing list stated that they had created similar solutions themselves. Thus, my suggestion is to simply build such functionality directly into the language. While scanning the built-in functions page (I don't use any, all, or enumerate nearly enough), I noticed the object() function, and since its purpose is to return a featureless object, it seems to fit the bill quite well. Adding my suggested functionality should break nothing (since the kwargs would be optional) and would allow people to stop baking their own solutions to this common problem, while getting the speed bonus of a C implementation (if it helps). Thus, the code above becomes for... employees[ssn] = object(ssn=ssn, first=first, last=last, salary=salary) employees[SSN].first Does anyone else think this might be a good idea for Python 2.6/3K? Thanks, Brandon
![](https://secure.gravatar.com/avatar/d8e1829f34ff2b7d71c3718c84a865c9.jpg?s=120&d=mm&r=g)
On Thu, May 22, 2008 at 12:21 AM, Brandon Mintern <bmintern@gmail.com> wrote:
I would like to propose to change the built-in function "object" to have the following syntax:
object(**kwargs) Return a new featureless object. object is a base for all new style classes. It has the methods that are common to all instances of new style classes.
If kwargs is given, the returned object's __dict__ will be kwargs (or something to that effect).
python 2.6 and 3.0 has something similar to this with collections.namedtuple: http://docs.python.org/dev/3.0/library/collections.html#collections.namedtup... The interface is a bit more verbose though:
Point = namedtuple('Point', 'x y') p = Point(11, y=22) # instantiate with positional or keyword arguments p[0] + p[1] # indexable like the plain tuple (11, 22) 33 x, y = p # unpack like a regular tuple x, y (11, 22) p.x + p.y # fields also accessible by name 33 p # readable __repr__ with a name=value style Point(x=11, y=22)
I like the syntax of using arguments to object though. Maybe there's a discussion behind namedtuple why they went that way instead of this one?
![](https://secure.gravatar.com/avatar/f218712e0ab1f61e87ba9f28d84f6734.jpg?s=120&d=mm&r=g)
On Thu, 22 May 2008, Erick Tryzelaar wrote:
python 2.6 and 3.0 has something similar to this with collections.namedtuple:
http://docs.python.org/dev/3.0/library/collections.html#collections.namedtup...
The interface is a bit more verbose though:
Point = namedtuple('Point', 'x y') p = Point(11, y=22) # instantiate with positional or keyword arguments p[0] + p[1] # indexable like the plain tuple (11, 22) 33 x, y = p # unpack like a regular tuple x, y (11, 22) p.x + p.y # fields also accessible by name 33 p # readable __repr__ with a name=value style Point(x=11, y=22)
I like the syntax of using arguments to object though. Maybe there's a discussion behind namedtuple why they went that way instead of this one?
Just like lambdas were gotten rid of in favor of named inner functions (in part) for readability, it sounds like readability would be a strong argument for using namedtuple rather than some kind of an anonymous object. -- Cheers, Leif
![](https://secure.gravatar.com/avatar/bf0ee222dbef43f7743772df65fa8ac8.jpg?s=120&d=mm&r=g)
Just like lambdas were gotten rid of in favor of named inner functions (in part) for readability, it sounds like readability would be a strong argument for using namedtuple rather than some kind of an anonymous object.
-- Cheers, Leif
My only argument would be that classic usage of lambda had three main purposes: (1) to create a function that is assigned to a variable, in which case using def makes more sense, (2) to pass to functions like map and filter, where the same functionality can be achieved with list comprehensions, and (3) to pass to other functions. Getting rid of lambda helps to eliminate the fallacy that is purpose 1, with list comprehensions purpose 2 is less necessary, and purpose 3 is the only real casualty. Even when you really do want to pass a lambda, it's not very hard to say: def f (x): return x*x and then simply pass the f. Thus getting rid of lambda helps alleviate a few issues while not hurting too badly. With an anonymous object, however, I feel the case is a bit different. You are not really using it to create an anonymous class, or even a named tuple. You are instead using it to create an instance of object which already has some fields defined. The same thing could be accomplished with: class anonobject: pass a = anonobject() a.one = 1 a.two = 2 But there is really no easier way that I can think of to do this on the fly except to have already built a Record class as I previously indicated. As long as this is the case, many users will be implementing their own Record class with all the inefficiencies and errors that come along with that. For example, my first iteration looked like: class Fields: """ A class intended to provide a simple interface for creating objects with named fields. That is, instead of returning a tuple and indexing it or writing a unique class, you can simply do something like: a = Fields(x=1, y=2) a.x # 1 a.y # 2 """ def __init__ (self, **kwargs): for name, value in kwargs.iteritems(): self.__dict__[name] = value Not horrible, but it still failed to utilize dict.update(), and the original name was much less intuitive. Someone reading my code would likely have to check out the Fields source to see what exactly I'm doing. Come to think of it, the change to object that I am suggesting could even place the kwargs in __slots__ so that the instance it returns is similar to that currently returned by object(), in that it is not possible to add new fields. All in all, though, I feel like such a change would actually *improve* code readability in general, as we would be less likely to use a tuple or a dict to hold what is truly an object. As soon as it becomes apparent that our object is being used in more complicated ways, it should be easy to write our own class with the same fields as our original call to object and drop it in, adding a reasonable constructor, methods, etc.
![](https://secure.gravatar.com/avatar/cd6aae9615c3b36130e2470902833a72.jpg?s=120&d=mm&r=g)
Brandon Mintern wrote:
The same thing could be accomplished with:
class anonobject: pass a = anonobject() a.one = 1 a.two = 2
But there is really no easier way that I can think of to do this on the fly except to have already built a Record class as I previously indicated.
There is an "easier" way, for some definitions of "easy": a=type('anonobject', (object,), {})() # a is an instance of class anonobject a.one = 1 a.two = 2 Or if you want to keep it really short: a=type('anonobject', (object,), dict(one=1, two=2)) # a is a class named anonobject I'll grant that this looks ugly, the intent of the code is far from obvious. But if you don't do this too often and place appropriate comments this should be fine. If you do find yourself doing this often, I would say writing an appropriate class is the best solution; it is certainly what I would have done in your example with the employees. - Tal
![](https://secure.gravatar.com/avatar/7e4e7569d64e14de784aca9f9a8fffb4.jpg?s=120&d=mm&r=g)
On Thu, May 22, 2008, Leif Walsh wrote:
Just like lambdas were gotten rid of in favor of named inner functions (in part) for readability, it sounds like readability would be a strong argument for using namedtuple rather than some kind of an anonymous object.
Um, what? lambda is still here... -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ Need a book? Use your library!
![](https://secure.gravatar.com/avatar/7e4e7569d64e14de784aca9f9a8fffb4.jpg?s=120&d=mm&r=g)
On Thu, May 22, 2008, Brandon Mintern wrote:
I would like to propose to change the built-in function "object" to have the following syntax:
object(**kwargs) Return a new featureless object. object is a base for all new style classes. It has the methods that are common to all instances of new style classes.
Enh. It's easy enough to write class Obj: def __init__(self, **kwargs): self.__dict__.update(kwargs) It's not clear to me that your functionality is desired frequently enough *in that specific form* to warrant changing object(). Note particularly the emphasis; over the years, I've seen various small variations in how people want kwargs processed and it's not at all clear to me that codifying one specific form into the language would be helpful. -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ Need a book? Use your library!
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Thu, May 22, 2008 at 5:22 AM, Aahz <aahz@pythoncraft.com> wrote:
On Thu, May 22, 2008, Brandon Mintern wrote:
I would like to propose to change the built-in function "object" to have the following syntax:
object(**kwargs) Return a new featureless object. object is a base for all new style classes. It has the methods that are common to all instances of new style classes.
Enh. It's easy enough to write
class Obj: def __init__(self, **kwargs): self.__dict__.update(kwargs)
It's not clear to me that your functionality is desired frequently enough *in that specific form* to warrant changing object(). Note particularly the emphasis; over the years, I've seen various small variations in how people want kwargs processed and it's not at all clear to me that codifying one specific form into the language would be helpful.
This is the answer that came to my mind. Also note that not all classes give their instances a __dict__, and object (being the simplest object possible) does not -- so object(foo=1) wold not have a place where to store the 'foo': 1 mapping. -- --Guido van Rossum (home page: http://www.python.org/~guido/)
![](https://secure.gravatar.com/avatar/d2ec49630ec52be314d888791ea86143.jpg?s=120&d=mm&r=g)
Start using those and suddenly you are going to have lots of little anonymous objects around and you'll start to want to add functionality to them and otherwise enforce things about them. Now you have a higher barrier than when you would have been creating it from scratch. and remember, object is not a function. It is a type. It is the base type of all types and so this has implications beyond what you suggest it for. If object(a=10).a == 10, then when custom classes' __init__ methods upcall, they'll start to fall back on letting kwargs fall up to object.__init__ to set initialization attributes. Now we gain this rule of thumb that keyword arguments are probably going to end up as attributes, because if we don't 'catch' them and they reach object.__init__, they will be. This isn't a behavior the language should encourage, because it should be left up to the developer. Currently, object.__init__ specifically takes any arguments and does nothing with any of them. This is to allow upcall in your __init__ gracefully, because if the upclass is one of your bases or the final base, object, you can still pass your parameters along safely. Implying some behavior when it reaches object.__init__, especially (in most cases) after you've initialized your object, would probably just trounce all over your object and piss you off. No thanks. On May 22, 2008, at 3:21 AM, Brandon Mintern wrote:
I would like to propose to change the built-in function "object" to have the following syntax:
object(**kwargs) Return a new featureless object. object is a base for all new style classes. It has the methods that are common to all instances of new style classes.
If kwargs is given, the returned object's __dict__ will be kwargs (or something to that effect).
An example:
a = object(one=1, two=2) a.one # returns 1 a.two # returns 2
The justification:
On several occasions I have needed a collection of attributes to represent a single item. When this happens, there are really three options:
1. Use a tuple. This works well for temporarily re-packaging items in a loop or for quick-and-dirty code, but it rapidly becomes unreadable and hard to maintain. It is not long before you forget what order the attributes are in, and at first glance, it is not clear what kind of object is being indexed.
2. Use a dict. This is an improvement over tuples on readability, but they can be a pain to build and overly-cumbersome to access later. I understand that dicts are used all over the place in Python, but I still think of them (in the general case) as a map of keys to values where the dict represents a collection, not an object.
3. Use a class. This requires coming up with a name for the class and then writing the class (admittedly, this should be easy). Afterwards, this is the most convenient, readable method for representing the data, but since it requires non-trivial effort up front, this method may be avoided until it's truly apparent that it is necessary.
A real-world example:
Let's say that I want to have a map of employee SSNs to employee data. I am going to be manipulating this information in various ways, but not really in any ways that justify the use of class methods. At any rate, let's build this data from a file where each line is
SSN First Last Salary
with the items being whitespace-delimited. The code, then, will be:
employees = {} for ssn, first, last, salary in (line.split() for line in open (employee_file)): employees[ssn] = (ssn, first, last, salary) # tuple method employees[ssn] = {"ssn": ssn, "first": first, "last": last, "salary": salary} # dict method employees[ssn] = Employee(ssn, first, last, salary) # assumes class with proper constructor
# first name of employee with SSN employees[SSN][1] # tuple method -- quite unreadable employees[SSN]["first"] # dict method -- more readable but sub-optimal employees[SSN].first # class method -- readable and simple
Now, because of the advantages the class method offers in terms of readability, I have written a convenience class that makes using it easier:
class Record: """ A class intended to provide a simple interface for creating objects with named fields. That is, instead of returning a tuple and indexing it or writing a unique class, you can simply do something like: a = Record(x=1, y=2) a.x # 1 a.y # 2 a # Record(x=1, y=2) """ def __init__ (self, **kwargs): self.__dict__.update(kwargs)
def __repr__ (self): return "Record(%s)" \ % ", ".join("%s=%s" \ % field for field in self.__dict__.iteritems())
Now, the line in the for loop above becomes
employees[ssn] = Record(ssn=ssn, first=first, last=last, salary=salary)
and I have completely avoided the need to define a unique class. Note that as the number of fields increases, this becomes easier to use inline than the dict method, at the same time that it avoids the upfront costs of having to build a new class for every distinct type of object in the program.
It turns out that other people find such a method useful as well. According to Catherine Devlin on the centralOH Python list, it is recipe 4.18 from the Python Cookbook (2nd ed.). Several others from the mailing list stated that they had created similar solutions themselves.
Thus, my suggestion is to simply build such functionality directly into the language. While scanning the built-in functions page (I don't use any, all, or enumerate nearly enough), I noticed the object() function, and since its purpose is to return a featureless object, it seems to fit the bill quite well. Adding my suggested functionality should break nothing (since the kwargs would be optional) and would allow people to stop baking their own solutions to this common problem, while getting the speed bonus of a C implementation (if it helps).
Thus, the code above becomes
for... employees[ssn] = object(ssn=ssn, first=first, last=last, salary=salary)
employees[SSN].first
Does anyone else think this might be a good idea for Python 2.6/3K?
Thanks, Brandon _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
![](https://secure.gravatar.com/avatar/bf0ee222dbef43f7743772df65fa8ac8.jpg?s=120&d=mm&r=g)
A lot to address here. On Thu, May 22, 2008 at 9:43 AM, Calvin Spealman <ironfroggy@socialserve.com> wrote:
Start using those and suddenly you are going to have lots of little anonymous objects around and you'll start to want to add functionality to them and otherwise enforce things about them. Now you have a higher barrier than when you would have been creating it from scratch.
That wasn't my intended use case, though. I wouldn't be using an anonymous object in more than one place to create the same type of object. In that case, actually defining a class or using NamedTuple (or some equivalent) clearly wins out. This would be a similar situation to that of lambda. You would not use lambda in several different places to define the same function; as soon as you start to write it a second time, you'd be much better to def the function and use it in both places. My main use case is in packing related information together for convenience and readability when passing it around to several different functions. In other words, the exact case where someone might be tempted to use a tuple (in spite of poor readability later) or a dict (in spite of a cumbersome access pattern). If you're using it for a case like this and you later decide that you should expand the anonymous object to a full-blown class, you would only have to change it in one place. Moreover, it would be much easier than changing a tuple or dict to a class. In the anonymous object situation, you only have to change the one instantiation; as long as you create a class with the same field names, your other accesses are still valid. In the tuple or dict cases, however, you have to change the code everywhere that you are using the object. Thus, I feel that having an anonymous object available actually lowers the barrier to making smart changes to the code.
and remember, object is not a function. It is a type. It is the base type of all types and so this has implications beyond what you suggest it for. If object(a=10).a == 10, then when custom classes' __init__ methods upcall, they'll start to fall back on letting kwargs fall up to object.__init__ to set initialization attributes. Now we gain this rule of thumb that keyword arguments are probably going to end up as attributes, because if we don't 'catch' them and they reach object.__init__, they will be. This isn't a behavior the language should encourage, because it should be left up to the developer. Currently, object.__init__ specifically takes any arguments and does nothing with any of them. This is to allow upcall in your __init__ gracefully, because if the upclass is one of your bases or the final base, object, you can still pass your parameters along safely. Implying some behavior when it reaches object.__init__, especially (in most cases) after you've initialized your object, would probably just trounce all over your object and piss you off.
This is a very good argument for why object() should not be used for this purpose; you have completely changed my mind. I still think there would be value in having a built-in function for declaring such objects. Perhaps a function (constructor) named struct(**kwargs) would be appropriate? On Thu, May 22, 2008 at 8:22 AM, Aahz <aahz@pythoncraft.com> wrote:
Enh. It's easy enough to write
class Obj: def __init__(self, **kwargs): self.__dict__.update(kwargs)
Yes, it is easy enough, once you have worked with Python a lot. Personally, I didn't know much at all about __dict__ or **kwargs when I first started, and looking back at my old code now, there are several places where I have used tuples or dicts and the code is hard to manage. Having a struct type to hold related information which does not justify a full class would have been very nice.
It's not clear to me that your functionality is desired frequently enough *in that specific form* to warrant changing object(). Note particularly the emphasis; over the years, I've seen various small variations in how people want kwargs processed and it's not at all clear to me that codifying one specific form into the language would be helpful. No thanks.
This is another good argument for why object() should not be used for this purpose. I still think that adding a new type "struct" would have several benefits. Others wrote:
NamedList, NamedDict, NamedTuple...
I agree that these are very useful functions to have when what you really want to do is just subclass the indicated type. For the use case I have in mind, however, they have much more functionality (and take up more space?) than necessary, and specifically having to decide on and declare a name that will never be used constitutes wasted effort. I will be sending out a new reply with my updated proposal, using the name "struct" instead of multi-purposing object, as that is clearly a bad idea. Thanks for all the constructive criticism and feedback, Brandon
![](https://secure.gravatar.com/avatar/72ee673975357d43d79069ac1cd6abda.jpg?s=120&d=mm&r=g)
Calvin Spealman wrote:
and remember, object is not a function. It is a type. It is the base type of all types and so this has implications beyond what you suggest it for.
Another serious consequence is that supporting this would require the object type to have a __dict__, which would force *all* types, including the built-in ones, to have the overhead of a __dict__ as well. -- Greg
![](https://secure.gravatar.com/avatar/0e6cf1b640884b3bd0378810757c1bb0.jpg?s=120&d=mm&r=g)
On Thu, May 22, 2008 at 12:21 AM, Brandon Mintern <bmintern@gmail.com> wrote:
I would like to propose to change the built-in function "object" to have the following syntax:
object(**kwargs) Return a new featureless object. object is a base for all new style classes. It has the methods that are common to all instances of new style classes.
I agree this is a useful pattern. One thing I don't like about it is that: object(x=1, y=2) looks very much like object(x=1, y=2, z=3) and I probably won't discover I've been given the wrong one until it's too late. I think it can better addressed by implementing NamedList and NamedDict: NamedList(typename, fieldnames[, optionalfields[, verbose]]) Returns a new list subclass named typename. The new subclass is used to create list-like objects that have fields accessible by attribute lookup as well as supporting other list operations. Instances of a NamedList may be created using a mixture of positional and keyword arguments. If optionalfields is not true, then the NamedList must always contain at least as many elements as the number of fields. If the NamedDict contains fewer elements than the number of fields, missing fields return None when accessed by attribute (a.third) and raise IndexError when accessed by index (a[3]). NamedDict(typename, fieldnames[, optionalfields[, verbose]]) Returns a new dict subclass named typename. The new subclass is used to create dict-like objects that have fields accessible by attribute lookup as well as supporting other dict operations. Instances of a NamedDict may be created using keyword arguments only. If optionalfields is not true, then the NamedDict must have a value for every field. If a NamedDict does not contain a field, accessing it returns None when accessed by attribute (a.x) and raises KeyError when accessed using by key (a['x']). --- Bruce
![](https://secure.gravatar.com/avatar/f218712e0ab1f61e87ba9f28d84f6734.jpg?s=120&d=mm&r=g)
On Thu, 22 May 2008, Bruce Leban wrote:
I think it can better addressed by implementing NamedList and NamedDict:
Oh no...
NamedList(typename, fieldnames[, optionalfields[, verbose]])
Returns a new list subclass named typename. The new subclass is used to create list-like objects that have fields accessible by attribute lookup as well as supporting other list operations. Instances of a NamedList may be created using a mixture of positional and keyword arguments. If optionalfields is not true, then the NamedList must always contain at least as many elements as the number of fields. If the NamedDict contains fewer elements than the number of fields, missing fields return None when accessed by attribute (a.third) and raise IndexError when accessed by index (a[3]).
Is this just a variable-length version of NamedTuple? It doesn't seem to offer very much over NamedTuple to me, but I'm open to convincing.
NamedDict(typename, fieldnames[, optionalfields[, verbose]])
Returns a new dict subclass named typename. The new subclass is used to create dict-like objects that have fields accessible by attribute lookup as well as supporting other dict operations. Instances of a NamedDict may be created using keyword arguments only. If optionalfields is not true, then the NamedDict must have a value for every field. If a NamedDict does not contain a field, accessing it returns None when accessed by attribute (a.x) and raises KeyError when accessed using by key (a['x']).
This one, though, doesn't sound any different from a struct-style class, except that it's easier (by ".__dict__") to access the class as a dictionary. Hell, here you go:
class NamedDict(object): def __getitem__(self, key): return self.__dict__[key]
-- Cheers, Leif
![](https://secure.gravatar.com/avatar/0e6cf1b640884b3bd0378810757c1bb0.jpg?s=120&d=mm&r=g)
On Thu, May 22, 2008 at 11:47 AM, Leif Walsh <adlaiff6@gmail.com> wrote:
On Thu, 22 May 2008, Bruce Leban wrote:
I think it can better addressed by implementing NamedList and NamedDict:
Oh no...
NamedList(typename, fieldnames[, optionalfields[, verbose]])
Returns a new list subclass named typename. The new subclass is used to create list-like objects that have fields accessible by attribute lookup as well as supporting other list operations. Instances of a NamedList may be created using a mixture of positional and keyword arguments. If optionalfields is not true, then the NamedList must always contain at least as many elements as the number of fields. If the NamedDict contains fewer elements than the number of fields, missing fields return None when accessed by attribute (a.third) and raise IndexError when accessed by index (a[3]).
Is this just a variable-length version of NamedTuple? It doesn't seem to offer very much over NamedTuple to me, but I'm open to convincing.
Tuples are immutable. Lists are mutable. The reason I suggest making it variable length is so that it supports the full list semantics and you could for example create a NamedList object with no values and then add values to it (ditto for NamedDict).
NamedDict(typename, fieldnames[, optionalfields[, verbose]])
Returns a new dict subclass named typename. The new subclass is used to create dict-like objects that have fields accessible by attribute lookup as well as supporting other dict operations. Instances of a NamedDict may be created using keyword arguments only. If optionalfields is not true, then the NamedDict must have a value for every field. If a NamedDict does not contain a field, accessing it returns None when accessed by attribute (a.x) and raises KeyError when accessed using by key (a['x']).
This one, though, doesn't sound any different from a struct-style class, except that it's easier (by ".__dict__") to access the class as a dictionary. Hell, here you go:
class NamedDict(object): def __getitem__(self, key): return self.__dict__[key]
Well, I think the "Named" aspect is important. For example, repr(x) tells you the name. I can tell if two objects are the same type. Also the NamedDict supports attribute access to the specific fields you've declared and no others. So it's not a freewheeling object that you can add any attribute to it. It's just a lightweight way to create an object backed by a dict (just as NamedTuple is).
-- Cheers, Leif
![](https://secure.gravatar.com/avatar/f218712e0ab1f61e87ba9f28d84f6734.jpg?s=120&d=mm&r=g)
On Thu, 22 May 2008, Bruce Leban wrote:
Tuples are immutable. Lists are mutable. The reason I suggest making it variable length is so that it supports the full list semantics and you could for example create a NamedList object with no values and then add values to it (ditto for NamedDict).
I might be wrong here, but I think one of the reasons NamedTuple was decided upon (its immutability, specifically) was a performance issue. It's a lot easier to optimize a struct when you know exactly what its fields are. I think making a mutable one of these is really not offering all that much advantage to anyone in a large number of cases.
Well, I think the "Named" aspect is important. For example, repr(x) tells you the name. I can tell if two objects are the same type.
Well, right. That's the point of a struct-style class. You name it whatever you would like.
Also the NamedDict supports attribute access to the specific fields you've declared and no others. So it's not a freewheeling object that you can add any attribute to it. It's just a lightweight way to create an object backed by a dict (just as NamedTuple is).
I'm confused. I thought you said you wanted mutability. Now you can only have the fieldnames you specify in the beginning? This is not really how a dict usually operates. That said, you can mess with __slots__ all you want in your free time, but I think we're straying pretty far from "one obvious way" here. -- Cheers, Leif
participants (10)
-
Aahz
-
Brandon Mintern
-
Bruce Leban
-
Calvin Spealman
-
Erick Tryzelaar
-
George Sakkis
-
Greg Ewing
-
Guido van Rossum
-
Leif Walsh
-
Tal Einat