0

In an attempt to format my code a little better to avoid redundancies in multiple methods doing the same stuff for different classes, I'm faced with the following problem :

# problematic method
def a(self, b, c):
    result = test(b)
    if (result):
        c = None # <- local variable c is assigned but never used
    return

# main code
obj.a(obj.b, obj.c)

And the obj's variable c is never set to None.

The current working code that I'm trying to reformat is the following :

# working method
def a(self):
   result = test(self.b)
   if (result):
       self.c = None
   return

# main code
obj.a()
user3548298
  • 186
  • 1
  • 1
  • 13
  • [Why can a function modify some arguments as perceived by the caller, but not others?](//stackoverflow.com/q/575196) – Aran-Fey Nov 02 '18 at 10:38
  • 1
    Possible duplicate of [Why can a function modify some arguments as perceived by the caller, but not others?](https://stackoverflow.com/questions/575196/why-can-a-function-modify-some-arguments-as-perceived-by-the-caller-but-not-oth) – Léopold Houdin Nov 02 '18 at 10:42
  • It's a bit different as I'm working with instance variables. In both cases the code should do exactly the same, if we simply replace "b" and "c" but the input arguments – user3548298 Nov 02 '18 at 10:45
  • 2
    The linked question explains why assigning to `c` doesn't do anything. And it's really not clear why you want to rewrite the `a` method anyway. It already works, why are you breaking it? – Aran-Fey Nov 02 '18 at 10:49
  • The above code has been simplified to highlight the real problem. In my program, I have several of those a() methods with more lines of codes in it, but depending on which one is called, they work on different variables of my object (but they all do the same thing so I want to regroup them in one method so that if I want to optimize it, I wouldn't have to do it everywhere) – user3548298 Nov 02 '18 at 10:52

2 Answers2

1

See Why can a function modify some arguments as perceived by the caller, but not others? for an explanation why reassigning c in a doesn't update obj.c.

If you want to pass a reference to an object attribute to a function, you have to pass it two things:

  1. the object
  2. the name of the attribute (i.e. a string)

You can then dynamically set that attribute from inside the function:

def a(self, b, name_of_c):
    result = test(b)
    if result:
        setattr(self, name_of_c, None)

obj.a(obj.b, 'c')
Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
-2

At the end of your def a routine, assign 'c' to itself,
it will not make a difference when the code is executed, since it is declared after the return... this will get rid of the annoying warning. And it's simple to understand when reviewing in the future

def a(self, b, c): result = test(b) if (result): c = None # <- local variable c is assigned but never used return

#This will never run since it is after the return #but it will get rid of the annoying assigned but #never used warning c = c

P_A_N
  • 1
  • 1
  • This is incorrect. `c = None` in OP's code truly does nothing and therefore does not perform as intended. See other answers for more info – roeen30 Dec 11 '22 at 14:20