Terminology

Mental model:

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

According to Python's glossary:

attribute: A value associated with an object which is referenced by name using dotted expressions. For example, if an object o has an attribute a it would be referenced as o.a

method: A function which is defined inside a class body. If called as an attribute of an instance of that class, the method will get the instance object as its first argument (which is usually called self). See function and nested scope.

Examples

Terminology applied to actual code:

a = 10                          # variable

def f(b):                       # function  
    return b ** 2

class C:

    c = 20                      # class attribute

    def __init__(self, d):      # "dunder" method
        self.d = d              # instance attribute

    def show(self):             # method
        print(self.c, self.d) 

e = C(30)
e.g = 40                        # another instance attribute
Answer from Raymond Hettinger on Stack Overflow
🌐
Alma Better
almabetter.com › bytes › tutorials › python › methods-and-attributes-in-python
Attributes and Methods in Python
February 29, 2024 - Attributes in Python are variables that belong to an object and contain information about its properties and characteristics. They can be used to represent details or facts related to the object.
Discussions

object oriented - Why are methods considered the class attributes in Python? - Software Engineering Stack Exchange
I read in a book that both methods and fields are considered the attributes of a class in Python. However, recently I was told by a friend of mine that methods may not be considered the attributes ... More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
August 1, 2013
Why doesn’t dir() separate attributes and methods apart?
You can however check for which are callable attributes: obj = [] print([attr for attr in dir(obj) if callable(getattr(obj, attr))]) # Prints ['__add__', '__class__', '__contains__', . . ., 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] More on reddit.com
🌐 r/learnpython
13
1
July 22, 2022
python - Differences between data attributes and method attributes - Stack Overflow
An attribute describes an object whilst a method acts on an object and changes it. ... Find the answer to your question by asking. Ask question ... See similar questions with these tags. ... Stack Overflow chat opening up to all users in January; Stack Exchange chat... ... 0 Python - Data Attributes vs ... More on stackoverflow.com
🌐 stackoverflow.com
python - Creating an attribute of an object versus a method in the class - Software Engineering Stack Exchange
More specifically for Python, you can define your derived value as a property instead of a method. You have the benefits of keeping the state to the minimum while still seemingly using an attribute (if that makes sense in your use case). More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
July 23, 2021
🌐
GeeksforGeeks
geeksforgeeks.org › python › accessing-attributes-methods-python
Accessing Attributes and Methods in Python - GeeksforGeeks
March 29, 2025 - Attributes represent the properties or characteristics of an object, while methods define the actions or behaviors that an object can perform. Understanding how to access and manipulate both ...
Top answer
1 of 1
10

Your friend was wrong. Methods are attributes.

Everything in Python is objects, really, with methods and functions and anything with a __call__() method being callable objects. They are all objects that respond to the () call expression syntax.

Attributes then, are objects found by attribute lookup on other objects. It doesn't matter to the attribute lookup mechanism that what is being looked up is a callable object or not.

You can observe this behaviour by looking up just the method, and not calling it:

>>> class Foo(object):
...     def bar(self):
...         pass
... 
>>> f = Foo()
>>> f.bar
<bound method Foo.bar of <__main__.Foo object at 0x1023f5590>>

Here f.bar is an attribute lookup expression, the result is a method object.

Of course, your friend me be a little bit right too; what is really happening is that methods are special objects that wrap functions, keeping references to the underlying instance and original function, and are created on the fly by accessing the function as an attribute. But that may be complicating matters a little when you first start out trying to understand Python objects. If you are interested in how all that works, read the Python Descriptor HOWTO to see how attributes with special methods are treated differently on certain types of attribute access.

This all works because Python is a dynamic language; no type declarations are required. As far as the language is concerned, it doesn't matter if Foo.bar is a string, a dictionary, a generator, or a method. This is in contrast to compiled languages, where data is very separate from methods, and each field on an instance needs to be pinned down to a specific type beforehand. Methods generally are not objects, thus a separate concept from data.

🌐
Quora
quora.com › What-is-the-difference-between-methods-and-attributes-in-Python
What is the difference between methods and attributes in Python? - Quora
Answer (1 of 2): Not just in python, ... etc.. attributes are the features of the objects or the variables used in a class whereas the methods are the operations or activities performed by that object defined as functions in the class...
🌐
Reddit
reddit.com › r/learnpython › why doesn’t dir() separate attributes and methods apart?
r/learnpython on Reddit: Why doesn’t dir() separate attributes and methods apart?
July 22, 2022 -

When exploring a new package I always find myself wanting what attributes are available in a class and what operations I can perform with it separately, but the dir() function just lumps them all together and displays them in a single list. After some searching around I still haven’t figured out how to just display all attributes or all methods of a class, and to this point I just wonder if I’m going the wrong way when learning about the basics of a newly installed package. Any advice or insights as to why python decided not to keep attributes and methods apart?

Thanks


Edit: Thanks all for the replies. Most of the answers pointed out that methods are just attributes that can be called. I think roughly get what it means, but don't quite understand why there is need to have both "method" and "attribute" concepts if they are just the same thing. Also, as I mentioned above, the reason I asked this question is that I always find myself wanting to know what attributes an object has, so I would print out dir(obj) and get a list of things [attr1, attr2, ...], then if I find, say, attr2 looks interesting/useful, I would try printing out obj.attr2 expecting to see some descriptive properties of the object, but the output would very often just tell me that attr2 is a method at some location... So I started wondering if I'm learning about a new package the wrong way, as I figure if most people do it the way I do, there should already be a function that does that!

🌐
Turing
turing.com › kb › introduction-to-python-class-attributes
A Guide to Python Class Attributes and Class Methods
They can be accessed using the class name and through an instance of the class. Class attributes are defined outside of any method, including the init method, and are typically assigned a value directly.
Find elsewhere
🌐
Medium
gokulapriyan.medium.com › understanding-python-class-components-attributes-methods-and-properties-explained-1b83402098ed
🔍 Understanding Python Class Components: Attributes, Methods, and Properties Explained” | by Gokulapriyan | Medium
September 26, 2024 - Introduction: In Python, classes are made up of three key parts: attributes, methods, and properties. Attributes store data, methods define actions, and properties help control access to data.
🌐
Python documentation
docs.python.org › 3 › tutorial › classes.html
9. Classes — Python 3.14.3 documentation
Creating a new class creates a new type of object, allowing new instances of that type to be made. Each class instance can have attributes attached to it for maintaining its state. Class instances can also have methods (defined by its class) for modifying its state.
🌐
YouTube
youtube.com › watch
Python 3 Tutorial for Beginners #18 - Methods & Attributes - YouTube
----- COURSE LINKS:+ Atom editor - https://atom.io/a+ CMDER - http://cmder.net/+ PYTHON - http://www.python.org/+ GitHub Repo - + GitHub Repo - https://githu...
Published   July 10, 2017
🌐
YouTube
youtube.com › watch
Python - Classes - Methods and Attributes - YouTube
In this video, we extend our definition of a class and look at attributes and methods. Let's look at a simple example as we build knowledge on object orienta...
Published   November 13, 2022
Top answer
1 of 5
34

An attribute is a variable that is looked up on another object using dot syntax: obj.attribute. The way Python is designed, attribute lookups can do a variety of things, and that variety can sometimes lead to bugs if you don't really understand what is happening (this is what the documentation you linked to warns about).

The most basic issue is that an attribute lookup can find either a value stored in the object's instance dictionary, or it can find something from the object's class (or a base class, if there's inheritance going on). Methods are functions stored in the class, but you usually use them by looking them up on an instance (which "binds" the method, inserting the object as the first arguemnt when the method is called).

The exact sequence of what is checked when is a bit complicated (I described the full process in an answer to another question), but at the most basic level, instance attributes usually take precedence over class attribute.

If an instance attribute and a class attribute with the same name both exist, usually only the instance attribute will be accessible. This can be very confusing if it is unintended.

Consider the following code:

class Foo(object):
    def __init__(self, lst):
        self.lst = lst

    def sum(self):
        self.sum = sum(self.lst)
        return self.sum

f = Foo([1,2,3])

print(f.sum())
print(f.sum())

At the bottom of this code, we make two identical calls. The first works just fine, but the second will raise an exception.

This is because the first time we look up f.sum we find a method in the Foo class. We can call the method with no problems. The trouble comes from the fact that the sum method assigns the result of its calculation (the sum of the elements in self.lst) to an instance attribute also named sum. This hides the sum method from view.

When second f.sum() call looks up f.sum, it finds the instance attribute, containing the integer 6, rather than the expected method. An integer is not callable, so we get an exception.

The solution, of course, is not to use the same name for the method and attribute. The code above is a pretty trivial example. The bugs caused by this sort of thing in more complex code can be much more difficult to figure out.

If you're writing code that adds attributes to objects you don't know much about, you should be careful to avoid common names. If you're writing a mixin class, consider using two leading underscores in the attribute names to trigger Python's name mangling, which is designed for exactly this sort of situation.


Addendum: It's also possible that the distinction the documentation is trying to make is between data and non-data descriptors. Methods are the most common kind of non-data descriptor, so it might make a degree of sense to call them "method attributes" (especially in contrast to "data attributes" which would be the corresponding name for data descriptors), though I'm not aware of that language being used more widely. The important difference between the two kinds of descriptors is that data descriptors (like property) get processed before the instance dictionary is checked for an ordinary instance variable. As discussed above, non-data descriptors like methods get processed only after the instance dictionary is checked, so they can be shadowed by data stored on the instance.

2 of 5
11

An attribute is any thing for the lack of a better word that is bound to an object, for example:

class Dog:
    def __init__(self):
        self.name = "Rufus"

    def bark(self):
        print "Woof Woof!"

In this case the data attribute is the name, which is simply a value that is bound to the instance of the Dog. As for a method attribute, one answer would be the bark method, as it's not so much a value as it is an action. It's just as it is in English. 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.

Top answer
1 of 1
4

Properly structured is subjective. :)

Generally, the more moving parts you have (i.e. mutable state), the harder it is to reason about your code. There are more pieces to fit in your mental model of the code, but there are additional concerns as well, such as ensuring the derived values stay coherent when a value is updated, or or that your code is correct if ran in a concurrent context. Therefore, I would consider leaving the calculation of the derived attributes in a method as a good default since it minimizes the state required.

Not all calculations are equal, however. It might be too computationally expensive to re-calculate the derived values every time they are needed (e.g. in a tight loop), at which time you might want to consider caching. The good thing is that if the computation is hidden in a method, caching simply becomes an implementation detail, leaving the rest of your code unaware of this optimization. If your use case warrants it, you may even use the Decorator pattern to implement this caching, decoupling the actual, interesting calculation from the technical details of caching.

More specifically for Python, you can define your derived value as a property instead of a method. You have the benefits of keeping the state to the minimum while still seemingly using an attribute (if that makes sense in your use case). That being said, a property is generally expected not to perform an expensive operation, so if that is your case, I would generally prefer to keep the method.

Top answer
1 of 1
14

Methods are attributes too. They just happen to be callable objects.

You can detect if an object is callable by using the callable() function:

>>> def foo(): pass
...
>>> callable(foo)
True
>>> callable(1)
False

When you call a method, you look up the attribute (a getattr() operation) and then call the result:

c.setAttr(newvalue)

is two steps; finding the attribute (which in this case looks up the attribute on the class, and treats it as a descriptor), then calls the resulting object, a method.

When you assign to an attribute, you rebind that name to a new value:

c.setAttr = 'something else'

would be a setattr() operation.

If you wanted to intercept getting and setting attributes on instances of your class, you could provide the attribute access hooks, __getattr__, __setattr__ and __delattr__.

If you wanted to add a method to an instance, you would have to treat the function as a descriptor object, which produces a method object:

>>> class Foo: pass
... 
>>> foo = Foo()  # instance
>>> def bar(self): pass
... 
>>> bar
<function bar at 0x10b85a320>
>>> bar.__get__(foo, Foo)
<bound method Foo.bar of <__main__.Foo instance at 0x10b85b830>>

The return value of function.__get__(), when given an instance and a class, is a bound method. Calling that method will call the underlying function with self bound to the instance.

And speaking of descriptors, the property() function returns a descriptor too, making it possible to have functions that behave like attributes; they can intercept the getattr(), setattr() and delattr() operations for just that attribute and turn it into a function call:

>>> class Foo:
...     @property
...     def bar(self):
...         return "Hello World!"
... 
>>> foo = Foo()
>>> foo.bar
"Hello World!"

Accessing .bar invoked the bar property get hook, which then calls the original bar method.

In almost all situations, you are not going to need the callable() function; you document your API, and provide methods and attributes and the user of your API will figure it out without testing each and every attribute to see if it is callable. With properties, you have the flexibility of providing attributes that are really callables in any case.

🌐
Python documentation
docs.python.org › 3 › reference › datamodel.html
3. Data model — Python 3.14.3 documentation
When an instance method object is derived from a classmethod object, the “class instance” stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function. It is important to note that user-defined functions which are attributes of a class instance are not converted to bound methods; this only happens when the function is an attribute of the class.
🌐
Medium
medium.com › @samersallam92 › 5-class-attributes-and-class-methods-in-python-oop-333dcfbb3578
Class Attributes and Class Methods: Python OOP Complete Course — Part 5
November 9, 2023 - Class attributes and class methods of classes and objects in Python oop. How to define class attributes and methods syntax and practical examples. Class method decorator.
🌐
Real Python
realpython.com › python-property
Python's property(): Add Managed Attributes to Your Classes – Real Python
December 15, 2024 - These programming languages need getter and setter methods because they don’t have a suitable way to change an attribute’s internal implementation when a given requirement changes. Changing the internal implementation would require an API modification, which can break your end users’ code. ... Technically, there’s nothing that stops you from using getter and setter methods in Python.
🌐
GeeksforGeeks
geeksforgeeks.org › difference-between-attributes-and-properties-in-python
Difference between attributes and properties in Python - GeeksforGeeks
December 12, 2015 - Python Method Method is called by its name, but it is associated to an object (dependent).A method d
🌐
Toptal
toptal.com › python › python-class-attributes-an-overly-thorough-guide
Python Class Attributes: An Overly Thorough Guide | Toptal®
January 16, 2026 - In Python, a class method is a method that is invoked with the class as the context. This is often called a static method in other programming languages. An instance method, on the other hand, is invoked with an instance as the context. In that case, the instance namespace takes precedence over the class namespace. If there is an attribute with the same name in both, the instance namespace will be checked first and its value returned.
🌐
Reddit
reddit.com › r/learnpython › when to use a property (rather than a method) in a class?
r/learnpython on Reddit: When to use a property (rather than a method) in a class?
December 15, 2023 -

Suppose I had the class `vehicle` which represents a motor vehicle. Suppose the horsepower of the vehicle was not passed as an inputs but, with some detailed calculation, could be calculated from the other properties of the vehicle class. Would it be better to add `horsepower` as a property of the `vehicle` class, or as a method?

As a property, this might look something like this:

class Vehicle:

    def __init__(self, args):
        # Set args
        self._horsepower = None
    
    @property
    def horsepower(self):
        if self._horsepower is None:
            self._horsepower = calculate_horsepower()
        return self._horsepower

As a method, it may look like this:

class Vehicle:

    def __init__(self, args):
        # Set args

    def calculate_horsepower(self):
        # Calculate horsepower of instance vehicle

Which of the above is preferable?

In reality, horsepower is a property of a vehicle. However, if significant processing is required to calculate it then I'm not sure if it feels right to have it as a property of the `vehicle` class.