1

I am defining a method within a class which creates a dictionary. This dictionary simply gives each letter of the alphabet a value. So the method doesn't manipulate any instances of that class. Do I need to have self as a parameter of the method in this case?

def build_shift_dict(self, shift):
    import string
    low = string.ascii_lowercase*2
    up = string.ascii_uppercase*2
    punc = list(" !@#$%^&*()-_+={}[]|\:;'<>?,./\"")
    shift_dict = {}

    for i in low[:26]:
        shift_dict[i] = low[low.index(i) + shift]

    for i in up[:26]:
        shift_dict[i] = up[up.index(i) + shift]

    for i in punc:
        shift_dict[i] = i

    return shift_dict
martineau
  • 119,623
  • 25
  • 170
  • 301
Mikki
  • 21
  • 1
  • 2
    Yes, if it is an instance method you need the `self` parameter because python will pass it in. Whether if *should* be an instance method is a different question. – Mark Dec 24 '20 at 16:28
  • I'll leave it for someone else to decide but I think https://stackoverflow.com/questions/7554738/python-self-no-self-and-cls and maybe https://stackoverflow.com/questions/37963018/in-python-when-self-can-be-omitted are probably duplicates – DavidW Dec 24 '20 at 16:32
  • Still not fully clear why "self" is needed in a method which not using the instance of the class, but I guess i need to take it as a given and apply @staticmethod instead – Mikki Dec 24 '20 at 19:14
  • @Mikki because the instance will automatically be assigned to the first argument of the function. If you leave out `self` and write `def build_shift_dict(shift):` then you won't have got a shift, but the instance will be called `shift`. The word `self` doesn't have any magical properties - it's just the number of arguments that's important. – DavidW Dec 24 '20 at 20:20

2 Answers2

5

No, you can just make it a static method

@staticmethod
def build_shift_dict(shift):
    ... do the things
tdelaney
  • 73,364
  • 6
  • 83
  • 116
1

In case you want to have a function that doesn't belong either to the Class' instance or to the class you can use @staticmethod decorator to the function, note that you need to remove self hence:

@staticmethod
def build_shift_dict(shift):
    import string
    low = string.ascii_lowercase*2
    up = string.ascii_uppercase*2
    punc = list(" !@#$%^&*()-_+={}[]|\:;'<>?,./\"")
    shift_dict = {}
    
    for i in low[:26]:   
            shift_dict[i] = low[low.index(i) + shift]
            
    for i in up[:26]:   
            shift_dict[i] = up[up.index(i) + shift]
            
    for i in punc:   
            shift_dict[i] = i
    
    return shift_dict     

Documentation

Other Stack Overflow Answers

Observations

For some, is considerated a good programming design to user staticmethods (or at least not all the time) and is normally better view the function to be declared outside of the class rather then use it within and then wrap it in a staticmethod, but really depends.

Also, declare a staticmethod or make a function outside a class is basically the same thing, hence is more a design choice rather than a functionality choice and is up to the designer / developer to choose which one is the best.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
Federico Baù
  • 6,013
  • 5
  • 30
  • 38