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.