Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Language Question: attributes of object() vs Function

In python, it is illegal to create new attribute for an object instance like this

>>> a = object()
>>> a.hhh = 1

throws

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

However, for a function object, it is OK.

>>> def f():
...   return 1
...
>>> f.hhh = 1

What is the rationale behind this difference?

like image 632
Anthony Kong Avatar asked Jul 02 '09 05:07

Anthony Kong


People also ask

What are object attributes in python?

An instance/object attribute is a variable that belongs to one (and only one) object. Every instance of a class points to its own attributes variables. These attributes are defined within the __init__ constructor.

What is difference between attributes and methods in Python?

A variable stored in an instance or class is called an attribute. A function stored in an instance or class is called a method.

How do you check attributes of an object in Python?

To check if an object in python has a given attribute, we can use the hasattr() function. The function accepts the object's name as the first argument 'object' and the name of the attribute as the second argument 'name. ' It returns a boolean value as the function output.

What is the difference between methods and data attributes of objects?

A data attribute is exactly as it sounds; it's data, it is simply a property. A method is a procedure, an action, and this is exactly what a method attribute is.


3 Answers

The reason function objects support arbitrary attributes is that, before we added that feature, several frameworks (e.g. parser generator ones) were abusing function docstrings (and other attribute of function objects) to stash away per-function information that was crucial to them -- the need for such association of arbitrary named attributes to function objects being proven by example, supporting them directly in the language rather than punting and letting (e.g.) docstrings be abused, was pretty obvious.

To support arbitrary instance attributes a type must supply every one of its instances with a __dict__ -- that's no big deal for functions (which are never tiny objects anyway), but it might well be for other objects intended to be tiny. By making the object type as light as we could, and also supplying __slots__ to allow avoiding per-instance __dict__ in subtypes of object, we supported small, specialized "value" types to the best of our ability.

like image 71
Alex Martelli Avatar answered Oct 27 '22 21:10

Alex Martelli


Alex Martelli posted an awesome answer to your question. For anyone who is looking for a good way to accomplish arbitrary attributes on an empty object, do this:

class myobject(object):
    pass

o = myobject()
o.anything = 123

Or more efficient (and better documented) if you know the attributes:

class myobject(object):
    __slots__ = ('anything', 'anythingelse')

o = myobject()
o.anything = 123
o.anythingelse = 456
like image 37
gahooa Avatar answered Oct 27 '22 21:10

gahooa


The rationale is that an instance of object() is a degenerate special case. It "is" an object but it isn't designed to be useful by itself.

Think of object as a temporary hack, bridging old-style types and classes. In Python 3.0 it will fade into obscurity because it will no longer be used as part of

class Foo( object ):
    pass

f = Foo()
f.randomAttribute = 3.1415926
like image 26
S.Lott Avatar answered Oct 27 '22 20:10

S.Lott