struct objects in python

The most concise way to make "a generic object to which you can assign/fetch attributes" is probably:

b = lambda:0

As most other answers point out, there are many other ways, but it's hard to beat this one for conciseness (lambda:0 is exactly the same number of characters as object()...;-).


From the Python Official Documentation:

9.7. Odds and Ends

Sometimes it is useful to have a data type similar to the Pascal “record” or C “struct”, bundling together a few named data items. An empty class definition will do nicely:

class Employee:
    pass

john = Employee() # Create an empty employee record

# Fill the fields of the record 
john.name = 'John Doe' 
john.dept = 'computer lab' 
john.salary = 1000

This seems natural and simple: Pythonic. Remember the Zen! "Simple is better than complex" (number 3) and "If the implementation is easy to explain, it may be a good idea" (number 11)

In addition, a struct is nothing but a class with public members (i.e., struct{}; and class{public:}; are the exact same thing (in, say, C++)). Shouldn't you consider this and avoid artificial constructs in your Python program? Python is supposed to be readable, maintainable, and easy to understand.


I had the same question once. I asked it in a mailing list, and Alex Martelli pointed out that object is the basis of all inheritance in Python; if object() created a class instance with its own dictionary, then every object in Python would have to have its own dictionary, and that would waste memory. For example, True and False are objects; clearly they don't have any need for their own dictionaries!

I would be happy if there was some sort of built-in Python feature where I could just say:

x = struct()
x.foo = 1
x.bar = 2

But it is trivial to write struct():

class struct(object):
    pass

Or you could do a slightly more complex one:

class struct(object):
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

The more complex one lets you do this:

x = struct(foo=1, bar=2)
print(x.foo) # prints 1
print(x.bar) # prints 2
x.baz = 3
print(x.baz) # prints 3

But it is so trivial to write struct() that I guess it wasn't deemed worth adding to the language. Maybe we should push to have a standard feature added to collections module or something.


I personally think that the cleanest solution is what you already guessed:

class Scratch(object):
    pass

s = Scratch()
s.whatever = 'you want'

I know you said that you don't want a __dict__, but that confuses me as I can't see a reason to care about that. You don't have to reference __dict__, that is an internal Python implementation detail. Anyway, any instance in Python that allows dynamically adding attributes will have a __dict__ because that's how Python does dynamic attributes. Even if the instance is created in a really clever way, it will have a __dict__.

If you have not already done so, I recommend reading PEP 20 and PEP 8. Not that the PEPs directly relate to your question, but I think it's useful in starting to use Python in a Pythonic manner.

Tags:

Python