Python Forum
Is it necessary to pass value of 'self' ?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Is it necessary to pass value of 'self' ?
#1
I am using VSCode for Python programming.

I have two files:
(1) pyMain
(2) pyTests

With this program I am learning to write unit tests using pyTest.

[pyMain.py]
class Mathematics:
    def AddNum(self,num1,num2):
        return num1+num2
    
    def SubtractNum(self,num1,num2):
        return num1-num2

[pyTests.py]

from pyMain import Mathematics
import pytest

def TestAddition():
    assert Mathematics.AddNum(1,5,6) == 11
    
def TestSubtraction():
    assert Mathematics.SubtractNum(1,6,3) == 3


TestAddition()
TestSubtraction()
I am not understanding why there is a need to pass value for 'self' in functions AddNum and SubtractNum. In pyTests.py, I am passing '1' to prevent error in the assert statements.
Reply
#2
Although they're part of your class, the way you've written the methods, they don't actually access any state of the class or the class instances (just passed in arguments). That really makes them static methods.

As such, you can declare them as such with the staticmethod decorator and then you don't have to pass in self (or the class).

class Mathematics:
    @staticmethod
    def AddNum(num1,num2):
        return num1+num2
     
    @staticmethod
    def SubtractNum(num1,num2):
        return num1-num2
Reply
#3
(Jul-12-2020, 08:59 PM)bowlofred Wrote: As such, you can declare them as such with the staticmethod decorator and then you don't have to pass in self (or the class).
@staticmethod is the way solve this,but i think this class should be used in normal way with a instantiating of a object in test function.

@rpk2006 take a look this and it can be smart to some reading about classes/OOP in Python.
class Mathematics:
    def add_num(self, num1, num2):
        '''I am method in class Mathematics and not a function'''
        return num1 + num2

    def subtract_num(self, num1, num2):
        return num1 - num2
Usage test:
>>> obj = Mathematics()
>>> obj.add_num(2, 7)
9
>>> obj.subtract_num(10, 3)
7
>>> 
>>> obj.add_num(7, 7) == 14
True
So the instantiation of obj can you to when testing this class.
So self do now become obj and can now pass 2 argument that the methods need.
Reply
#4
@bowlofred, @snippsat:

You mean to say if I don't instantiate, it is considered STATIC ?

Thanks for the answers.
Reply
#5
No, they're static because they have no self parameter.

I don't agree that the class should be instantiated - as mentioned above, it holds no state so why would you? I don't think this example calls for a class anyway; just simple functions would do. Why introduce complexity for no reason? If you wanted to namespace the functions, just put them in a "mathematics" module.
Reply
#6
If you write a class, then do it right.
You're able to change the behavior of classes.
For example, you can add a method for add and subtract.

With your provided example:
class MyValue:
    def __init__(self, value):
        self.value = value
    def __add__(self, other):
        '''I am method in class Mathematics and not a function'''
        return self.value + other.value
 
    def __sub__(self, other):
        return self.value - other.value


my_val1 = MyValue(5)
my_val2 = MyValue(4)

print(my_val1 + my_val2)
Output:
9
And if you want to have functions, which takes left and right operand and doing something with it, then just use regular functions.

def add(a, b):
    return a + b


def sub(a, b):
    return a - b

# or use operator add and sub from operator module:

from operator import add, sub

print(add(1,2))
print(add(2,3))
Output:
from operator import add, sub print(add(1,2)) print(add(2,3))
I guess you wanted the class, to stick the methods together.
If you have a regular method, then you have to instantiate the class to access the method.
A staticmethod does not supply the function with a reference to self nor to class.
To use this method, the class must be instantiated.

Finally, the classmethod allows calling methods directly on a class without creating an instance.

class Math:
    @classmethod
    def add(cls, a, b):
        return a + b

    @classmethod
    def sub(cls, a, b):
        return a - b


# calling the method on the class directly
print(Math.sub(1,2))
Output:
-1
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#7
I agree that class are not needed here and could have been written better as @DeaD_EyE show.
rpk2006 Wrote:With this program I am learning to write unit tests using pyTest.
As this is the goal,here i use your code in first post no change,and write some for it Pytest.
from math_class import Mathematics
import pytest

def test_base_calc():
    calc = Mathematics()
    assert calc.AddNum(2, 2) == 4
    assert calc.SubtractNum(2, 2) == 0

@pytest.mark.parametrize(
    'n1, n2, expected', [
        (4 , 5, 9),
        (11, 98523,  98534),
        (98652525, 52368745210, 52467397735),
    ]
)

def test_addtion(n1, n2, expected):
    calc = Mathematics()
    assert calc.AddNum(n1, n2) == expected

@pytest.mark.parametrize(
    'n1, n2, expected', [
        (12 , 6, 6),
        (456785, 3692,  453093),
        pytest.param(100, 35, 66, marks=pytest.mark.xfail),
    ]
)

def test_subtaction(n1, n2, expected):
    calc = Mathematics()
    assert calc.SubtractNum(n1, n2) == expected
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How to pass encrypted pass to pyodbc script tester_V 0 848 Jul-27-2023, 12:40 AM
Last Post: tester_V
  Pass by object reference when does it behave like pass by value or reference? mczarnek 2 2,548 Sep-07-2020, 08:02 AM
Last Post: perfringo
  Pass by reference vs Pass by value leodavinci1990 1 2,192 Nov-20-2019, 02:05 AM
Last Post: jefsummers

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020