0

What's the difference in Python Nested Function with Variables, and a Class with attributes and methods? I've looked online, asked a programmer, and still haven't figured how a class, is different than a function containing variables and other functions.

Example:

Class

class Add:
    def __init__(self):
        self.a = 5
        self.b = 7
    
    def inside_method(self):
        return (self.a + self.b)

add1 = Add()
print('sum is:', add1.inside_method())

Nested function with variables

def func():
    a = 5
    b = 7
    def nested_func():
        return (a + b)
    return nested_func()
    
print('sum is:', func())
uncoded0123
  • 167
  • 2
  • 13
  • 2
    You don't see any difference because your example doesn't make much sense in the first place. A class with no arguments in its `__init__` implementation (such as yours) is not very useful. – Selcuk Jun 18 '21 at 04:27
  • 2
    In your example, the class just adds unnecessary cruft without adding anything of value. But in general, classes can provide multiple methods and expose a convenient interface for an otherwise complicated operation or concept that perhaps can't be summed up in one function. – Silvio Mayolo Jun 18 '21 at 04:27
  • 3
    These are both similar, yet different approaches to the same thing -- encapsulating state. A class has various features built in with the language, e.g. inheritance, that you will not have using a closure over some variables and a higher order function. Of course, you could recreate that somehow, but then, you would just be re-implementing classes that are already a feature of the language – juanpa.arrivillaga Jun 18 '21 at 04:28
  • @juanpa.arrivillaga Thanks. So, classes have a lot of other features that nested functions don't? – uncoded0123 Jun 18 '21 at 04:36
  • 1
    How would you access the nested function from outside `func`? – Thierry Lathuille Jun 18 '21 at 04:50

2 Answers2

1

The comments on your question are already a good answer.

A Python method is just a function which have self as first argument, which is an instance of (an inheriting class of) the class that defines the method.

Indeed, for your very simple example, using a class is mostly useless. But you may be familiar with Python strings which are of the class str :

>>> type("hello")

And a string has many methods : capitalize, casefold, center, count, encode, endswith, ...

It is convenient because I don't need to create the same string each time for each method I want to call, I can reuse the same instance :

>>> s = "hello"
>>> s.capitalize()
"Hello"
>>> s.replace("h", "G")
'Gello'
>>> s.count("l")
2

What is even more powerfull is to use class instances to store state. Python strings are immutable, but lists are not.

>>> temperatures = [14, 15, 10, 33]
>>> temperatures[1]
15
>>> temperatures[1] = 0
>>> temperatures
[14, 0, 10, 33]
>>> temperatures.sort()
>>> [0, 10, 14, 33]

Object-orientation as it is implemented in Python is mostly about coupling statefull data with the functions to operate on it (named methods). It is aimed at simplifying these constructs which often useful.

Hope it clarifies !

Lenormju
  • 4,078
  • 2
  • 8
  • 22
  • Thanks, so the main difference is the ability to use dot notation in classes, but using functions only doesn't allow it? And the ability to create copies (instances) of the class and store/change variables and functions (methods) in those instances? – uncoded0123 Jun 19 '21 at 09:20
  • 1
    The main difference is about the structure of the code. You can use only functions, no objects/classes/methods, and be fine with it, it is actually called [functionnal programming](https://en.wikipedia.org/wiki/Functional_programming). But there are other paradigms like [object-oriented](https://en.wikipedia.org/wiki/Programming_paradigm) that offers different approaches and trade-offs. The "dot notation" here is just a detail, but it is indeed a difference between procedural and object-oriented. Here is a question about the subject : https://stackoverflow.com/q/60116769/11384184 – Lenormju Jun 20 '21 at 12:35
  • 1
    As for your second questions, "object-oriented" is a bit of an umbrella term, so there are many slightly different things called that way. But in the context of Python, yes, the fundamentals of OO is to define classes with methods, instantiating them and do things with their state. There is also inheritance, polymorphism, encapsulation, interfaces, abstract, ... which are OO concepts that you can use in Python to "model" your "domain" a certain way. If you still have more questions, best to create a new StackOverflow question and mark my answer as accepted :) – Lenormju Jun 20 '21 at 12:42
0

In my opinion, function is an abstraction of "action", and class is an abstraction of "thing". From this point of view, the members in function (local variables, closure variables, and nested function) are for assisting completing an "action" smoothly. On the other hand, the members of class (variables and methods inside it) are working together as an "object". The difference would be more clear when you trying to use them.

Just like Lenormju said, they are different paradigms. The purpose of choosing which one to fit your needs is all about how you want to abstract the real world. In your examples, it is more suitable to use nested function for Addition calculation.