-3

I am using the object function (object()) to make an object without a class in Python but it does not have any attributes or arguments, so I am trying to customise it by creating a variable like thing = object() and then using setattr(thing, 'name', 'Marco') but it won't let me because it throws an error saying:

>>> thing = object()
>>> setattr(thing, 'name', 'nothing')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'name'

How do I get past this? I don't get why it does this when object can't have attributes but the object function can (object()) and then it throws AttributeError when I try to set an attribute for the object that is assigned to the variable when the whole point of using setattr() is to set attributes lol

  • 1
    Does this answer your question? [Can't set attributes on instance of "object" class](https://stackoverflow.com/questions/1529002/cant-set-attributes-on-instance-of-object-class) – AlexK Apr 14 '21 at 00:22
  • https://stackoverflow.com/questions/5907937/adding-attributes-to-python-objects – Samwise Apr 14 '21 at 00:22
  • 1
    Every Python object has a class. What problem are you trying to solve by creating an object without a class? – user2357112 Apr 14 '21 at 00:24
  • 1
    Why don't you create a class with the attributes you require? – Nicholas Hunter Apr 14 '21 at 00:35

1 Answers1

3

To be clear, object() has a class (the class is object); it's impossible to have an instance without a class in Python.

That said, plain object doesn't have storage for arbitrary attributes. If you want a minimalist object that lets you make arbitrary attributes, use types.SimpleNamespace, e.g.:

import types  # At top of file

thing = types.SimpleNamespace()
setattr(thing, 'name', 'nothing')

Of course, setattr isn't necessary here since you're using known attribute names. Just use normal attribute assignment instead:

thing.name = 'nothing'

If you're really using dynamic attribute names via setattr, you're probably better off skipping attributes entirely, and just using a dict with dict lookup syntax:

thing = {}
thing['name'] = 'nothing'
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • I'd never heard of `SimpleNamespace` before today, neat! What are the differences between a `SimpleNamespace` and a `dataclass`? Seems like they do roughly the same thing. EDIT: never mind, I found this SO post: https://stackoverflow.com/questions/51082418/python-3-7-utility-of-dataclasses-and-simplenamespace – ddejohn Apr 14 '21 at 01:23
  • @ShadowRanger Your "solution" literally involves using classes – Marco El-Korashy Apr 14 '21 at 02:08
  • 3
    @MarcoEl-Korashy: Because it's literally impossible to avoid using classes. *Everything* in Python is an object, and all objects are instances of a class. The answer does explain that difficulty, and it does offer solutions that uses a minimalist built-in class to avoid defining new user-defined classes (which I suspect was the OP's goal). – ShadowRanger Apr 14 '21 at 03:40